mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-24 14:38:45 +00:00
Merge branch 'master' into bug5419
# Conflicts: # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/Refresher.java
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
FROM donaldduck70/sapjvm8:8.1.073
|
||||
FROM donaldduck70/sapjvm8:8.1.078
|
||||
LABEL maintainer=axel.uhl@sap.com
|
||||
# Download and extract the release
|
||||
WORKDIR /home/sailing/servers/server
|
||||
@@ -12,6 +12,7 @@ RUN wget -O /tmp/RELEASE.tar.gz http://releases.sapsailing.com/RELEASE/RELEASE.t
|
||||
&& tar xzvpf /tmp/RELEASE.tar.gz \
|
||||
&& rm /tmp/RELEASE.tar.gz
|
||||
COPY env.sh .
|
||||
RUN cat env-default-rules.sh >>env.sh
|
||||
COPY start .
|
||||
COPY JavaSE-11.profile .
|
||||
EXPOSE 8888 14888 8000 7091 6666
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
FROM buildpack-deps:stretch-scm
|
||||
FROM buildpack-deps:latest
|
||||
LABEL maintainer=axel.uhl@sap.com
|
||||
# Download and extract the SAP JVM 8
|
||||
ENV PATH=${PATH}:/opt/sapjvm_8/bin
|
||||
ENV JAVA_HOME=/opt/sapjvm_8
|
||||
WORKDIR /opt
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y wget unzip \
|
||||
&& curl --cookie eula_3_1_agreed=tools.hana.ondemand.com/developer-license-3_1.txt "https://tools.hana.ondemand.com/additional/sapjvm-7.1.073-linux-x64.zip" --output sapjvm8-linux-x64.zip \
|
||||
&& apt-get install -y wget apt-utils unzip \
|
||||
&& apt-get -y upgrade \
|
||||
&& curl --cookie eula_3_1_agreed=tools.hana.ondemand.com/developer-license-3_1.txt "https://tools.hana.ondemand.com/additional/sapjvm-8.1.078-linux-x64.zip" --output sapjvm8-linux-x64.zip \
|
||||
&& unzip sapjvm8-linux-x64.zip \
|
||||
&& rm sapjvm8-linux-x64.zip \
|
||||
&& echo "export JAVA_HOME=/opt/sapjvm_8; export PATH=\${PATH}:/opt/sapjvm_8/bin" > /etc/profile.d/javahome.sh
|
||||
|
||||
+6
-3
@@ -63,6 +63,9 @@ public enum BoatClassMasterdata {
|
||||
HOBIE_TIGER ("Hobie Tiger", true, 5.51, 2.60, BoatHullType.CATAMARAN, true),
|
||||
HOBIE_WILD_CAT ("Hobie Wild Cat", true, 5.49, 2.59, BoatHullType.CATAMARAN, true, "Hobie Wild Cat F18"),
|
||||
INTERNATIONAL_14("International 14", true, 4.27, 1.83, BoatHullType.MONOHULL, true, "I14", "Int.14", "Int14"),
|
||||
IQFOIL_MEN("iQFOil Men", true, 2.20, 0.95, BoatHullType.SURFERBOARD, false, "iQFOil 95 Men"),
|
||||
IQFOIL_WOMEN("iQFOil Women", true, 2.20, 0.95, BoatHullType.SURFERBOARD, false, "iQFOil 95 Women"),
|
||||
IQFOIL_YOUTH("iQFOil Youth", true, 2.15, 0.85, BoatHullType.SURFERBOARD, false, "iQFOil 85 Youth"),
|
||||
J22 ("J/22", true, 6.86, 2.44, BoatHullType.MONOHULL, true, "J22", "J-22"),
|
||||
J24 ("J/24", true, 7.32, 2.67, BoatHullType.MONOHULL, true, "J24", "J-24"),
|
||||
J70 ("J/70", true, 6.93, 2.25, BoatHullType.MONOHULL, true, "J70", "J-70"),
|
||||
@@ -76,9 +79,9 @@ public enum BoatClassMasterdata {
|
||||
KIELZUGVOGEL ("Kielzugvogel", true, 5.80, 1.88, BoatHullType.MONOHULL, false, "KZV"),
|
||||
FORMULA_KITE ("Kite", true, 3.35, 1.52, BoatHullType.MONOHULL, false, "Formula Kite"),
|
||||
LASER_2 ("Laser 2", true, 4.39, 1.42, BoatHullType.MONOHULL, false, "Laser II", "Laser2", "Laser-2", "Laser-II"),
|
||||
LASER_4_7 ("Laser 4.7", true, 4.20, 1.39, BoatHullType.MONOHULL, false, "L4.7"),
|
||||
LASER_RADIAL ("Laser Radial", true, 4.19, 1.41, BoatHullType.MONOHULL, false, "LAR", "Laser RAD", "RAD", "Radial"),
|
||||
LASER_INT ("Laser Int.", true, 4.19, 1.39, BoatHullType.MONOHULL, false, "Laser", "LSR", "Laser Standard"),
|
||||
LASER_4_7 ("Laser 4.7", true, 4.20, 1.39, BoatHullType.MONOHULL, false, "L4.7", "ILCA 4", "ILCA4"),
|
||||
LASER_RADIAL ("Laser Radial", true, 4.19, 1.41, BoatHullType.MONOHULL, false, "LAR", "Laser RAD", "RAD", "Radial", "ILCA 6", "ILCA6"),
|
||||
LASER_INT ("Laser Int.", true, 4.19, 1.39, BoatHullType.MONOHULL, false, "Laser", "LSR", "Laser Standard", "ILCA 7", "ILCA7"),
|
||||
LASER_SB3 ("Laser SB3", true, 6.15, 2.15, BoatHullType.MONOHULL, false, "LSB3", "SB20"),
|
||||
LAGO_26 ("Lago 26", true, 7.95, 2.50, BoatHullType.MONOHULL, true, "Lago26"),
|
||||
LONGTZE ("Longtze", true, 6.85, 2.57, BoatHullType.MONOHULL, true, "Swiss Longtze Class"),
|
||||
|
||||
+2
@@ -31,6 +31,7 @@ import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
@@ -131,6 +132,7 @@ public class WebSocketTest {
|
||||
Activator.getInstance().setSecurityService(null);
|
||||
}
|
||||
|
||||
@Ignore("echo.websocket.org is (2021-08-19) down; http://www.websocket.org/index.html says ''Service no longer available''")
|
||||
@Test
|
||||
public void simpleWebSocketEchoTest() throws Exception {
|
||||
String destUri = "ws://echo.websocket.org"; // wss currently doesn't seem to work with Jetty 9.0.4 WebSocket implementation
|
||||
|
||||
+3
-1
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.persistence.racelog.tracking;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
@@ -24,9 +25,10 @@ public interface MongoSensorFixStoreFactory {
|
||||
* Like {@link #getMongoGPSFixStore(MongoObjectFactory, DomainObjectFactory, TypeBasedServiceFinderFactory)}, but
|
||||
* additionally the write concern for the MongoDB writes can be controlled which otherwise usually defaults
|
||||
* to {@link WriteConcern#UNACKNOWLEDGED} for the fixes as well as the metadata.
|
||||
* @param readConcern TODO
|
||||
*/
|
||||
MongoSensorFixStore getMongoGPSFixStore(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory,
|
||||
TypeBasedServiceFinderFactory serviceFinderFactory, WriteConcern writeConcern)
|
||||
TypeBasedServiceFinderFactory serviceFinderFactory, ReadConcern readConcern, WriteConcern writeConcern)
|
||||
throws UnknownHostException, MongoException;
|
||||
|
||||
}
|
||||
+4
-2
@@ -48,13 +48,15 @@ public class MetadataCollection extends MongoFixHandler {
|
||||
private final MongoCollection<Document> metadataCollection;
|
||||
private final ConcurrentHashMap<DeviceIdentifier, MetadataUpdater> metadataUpdaters;
|
||||
private final WriteConcern writeConcern;
|
||||
private final ReadConcern readConcern;
|
||||
|
||||
public MetadataCollection(MongoObjectFactoryImpl mongoOF,
|
||||
TypeBasedServiceFinder<FixMongoHandler<?>> fixServiceFinder,
|
||||
TypeBasedServiceFinder<DeviceIdentifierMongoHandler> deviceServiceFinder, WriteConcern writeConcern) {
|
||||
TypeBasedServiceFinder<DeviceIdentifierMongoHandler> deviceServiceFinder, ReadConcern readConcern, WriteConcern writeConcern) {
|
||||
super(fixServiceFinder, deviceServiceFinder);
|
||||
this.metadataCollection = mongoOF.getGPSFixMetadataCollection();
|
||||
this.metadataUpdaters = new ConcurrentHashMap<>();
|
||||
this.readConcern = readConcern;
|
||||
this.writeConcern = writeConcern;
|
||||
}
|
||||
|
||||
@@ -74,7 +76,7 @@ public class MetadataCollection extends MongoFixHandler {
|
||||
*/
|
||||
private Document findMetadataObjectInternal(DeviceIdentifier device) throws TransformationException {
|
||||
Bson query = getDeviceQuery(device);
|
||||
Document result = metadataCollection.withReadConcern(ReadConcern.MAJORITY).find(query).first();
|
||||
Document result = metadataCollection.withReadConcern(readConcern).find(query).first();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.persistence.racelog.tracking.impl;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
@@ -21,7 +22,7 @@ public class MongoSensorFixStoreFactoryImpl implements MongoSensorFixStoreFactor
|
||||
@Override
|
||||
public MongoSensorFixStore getMongoGPSFixStore(MongoObjectFactory mongoObjectFactory,
|
||||
DomainObjectFactory domainObjectFactory, TypeBasedServiceFinderFactory serviceFinderFactory,
|
||||
WriteConcern writeConcern) throws UnknownHostException, MongoException {
|
||||
return new MongoSensorFixStoreImpl(mongoObjectFactory, domainObjectFactory, serviceFinderFactory, writeConcern);
|
||||
ReadConcern readConcern, WriteConcern writeConcern) throws UnknownHostException, MongoException {
|
||||
return new MongoSensorFixStoreImpl(mongoObjectFactory, domainObjectFactory, serviceFinderFactory, readConcern, writeConcern);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -17,6 +17,7 @@ import java.util.logging.Logger;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
@@ -72,16 +73,16 @@ public class MongoSensorFixStoreImpl extends MongoFixHandler implements MongoSen
|
||||
|
||||
public MongoSensorFixStoreImpl(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory,
|
||||
TypeBasedServiceFinderFactory serviceFinderFactory) {
|
||||
this(mongoObjectFactory, domainObjectFactory, serviceFinderFactory, WriteConcern.UNACKNOWLEDGED);
|
||||
this(mongoObjectFactory, domainObjectFactory, serviceFinderFactory, ReadConcern.DEFAULT, WriteConcern.UNACKNOWLEDGED);
|
||||
}
|
||||
|
||||
public MongoSensorFixStoreImpl(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory,
|
||||
TypeBasedServiceFinderFactory serviceFinderFactory, WriteConcern writeConcern) {
|
||||
TypeBasedServiceFinderFactory serviceFinderFactory, ReadConcern readConcern, WriteConcern writeConcern) {
|
||||
super(serviceFinderFactory != null ? createFixServiceFinder(serviceFinderFactory) : null,
|
||||
serviceFinderFactory != null ? serviceFinderFactory.createServiceFinder(DeviceIdentifierMongoHandler.class) : null);
|
||||
mongoOF = (MongoObjectFactoryImpl) mongoObjectFactory;
|
||||
fixesCollection = mongoOF.getGPSFixCollection();
|
||||
metadataCollection = new MetadataCollection(mongoOF, fixServiceFinder, deviceServiceFinder, writeConcern);
|
||||
metadataCollection = new MetadataCollection(mongoOF, fixServiceFinder, deviceServiceFinder, readConcern, writeConcern);
|
||||
this.writeConcern = writeConcern;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@ import java.util.UUID;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
@@ -84,7 +85,7 @@ public class AbstractGPSFixStoreTest extends RaceLogTrackingTestHelper {
|
||||
regattaLog = new RegattaLogImpl("regattalog");
|
||||
dropPersistedData();
|
||||
store = new MongoSensorFixStoreImpl(service.getMongoObjectFactory(), service.getDomainObjectFactory(),
|
||||
serviceFinderFactory, WriteConcern.MAJORITY);
|
||||
serviceFinderFactory, ReadConcern.MAJORITY, WriteConcern.MAJORITY);
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
||||
@@ -93,7 +94,7 @@ public class RaceLogFixTrackerManagerTest {
|
||||
raceLog2 = new RaceLogImpl("racelog2");
|
||||
regattaLog = new RegattaLogImpl("regattalog");
|
||||
store = new MongoSensorFixStoreImpl(PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(),
|
||||
PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory, WriteConcern.MAJORITY);
|
||||
PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory, ReadConcern.MAJORITY, WriteConcern.MAJORITY);
|
||||
Course course = new CourseImpl("course",
|
||||
Arrays.asList(new Waypoint[] { new WaypointImpl(mark), new WaypointImpl(mark2) }));
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
@@ -153,7 +154,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
raceLog.add(new RaceLogEndOfTrackingEventImpl(new MillisecondsTimePoint(END_OF_TRACKING), author, 0));
|
||||
regattaLog = new RegattaLogImpl("regattalog");
|
||||
store = new MongoSensorFixStoreImpl(PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(),
|
||||
PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory, WriteConcern.MAJORITY);
|
||||
PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory, ReadConcern.MAJORITY, WriteConcern.MAJORITY);
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(1), author,
|
||||
new MillisecondsTimePoint(1), 0, mark));
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(2), author,
|
||||
|
||||
+3
-3
@@ -8,11 +8,13 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
@@ -37,8 +39,6 @@ import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
public class SensorFixStoreTest {
|
||||
private static final long FIX_TIMESTAMP = 110;
|
||||
private static final long FIX_TIMESTAMP2 = 120;
|
||||
@@ -63,7 +63,7 @@ public class SensorFixStoreTest {
|
||||
|
||||
private void newStore() {
|
||||
store = new MongoSensorFixStoreImpl(PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(),
|
||||
PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory, WriteConcern.MAJORITY);
|
||||
PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory, ReadConcern.MAJORITY, WriteConcern.MAJORITY);
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
+1
-2
@@ -149,8 +149,7 @@ public class TracTracConnectivityParamsHandler extends AbstractRaceTrackingConne
|
||||
final String creatorName = SessionUtils.getPrincipal().toString();
|
||||
final TracTracConfigurationImpl tracTracConfiguration = new TracTracConfigurationImpl(creatorName, tractracRace.getEvent().getName(), jsonURL,
|
||||
(params.getLiveURI() == null ? null : params.getLiveURI().toString()),
|
||||
/* stored URI */ params.isPreferReplayIfAvailable() && params.isReplayRace(tractracRace)
|
||||
? null // we mainly want to enable the user to list the event's races again in case they are removed;
|
||||
/* stored URI */ params.isReplayRace(tractracRace) ? null // we mainly want to enable the user to list the event's races again in case they are removed;
|
||||
: (params.getStoredURI() == null ? null : params.getStoredURI().toString()), // live/stored stuff comes from the tracking params
|
||||
params.getCourseDesignUpdateURI()==null?null:params.getCourseDesignUpdateURI().toString(), params.getTracTracUsername(), params.getTracTracPassword());
|
||||
tractracMongoObjectFactory.updateTracTracConfiguration(tracTracConfiguration);
|
||||
|
||||
-1
@@ -56,7 +56,6 @@ public interface TracTracConfiguration extends WithQualifiedObjectIdentifier {
|
||||
}
|
||||
|
||||
public static TypeRelativeObjectIdentifier getTypeRelativeObjectIdentifier(String jsonUrl, String username) {
|
||||
|
||||
return username == null ? new TypeRelativeObjectIdentifier(jsonUrl)
|
||||
: new TypeRelativeObjectIdentifier(jsonUrl, username);
|
||||
}
|
||||
|
||||
+19
-3
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -7,6 +9,7 @@ import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
@@ -49,7 +52,12 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra
|
||||
private final GPSFixTrack<Competitor, GPSFixMoving> track;
|
||||
private final BoatClass boatClass;
|
||||
private final FixWindow fixWindow;
|
||||
private final TreeSet<GPSFixMoving> maneuverCandidates;
|
||||
|
||||
/**
|
||||
* The following set is a {@code synchronized} navigable set; all simple access methods synchronize trivially on it.
|
||||
* All iterations, including serializing this object, must {@code synchronize} on it.
|
||||
*/
|
||||
private final NavigableSet<GPSFixMoving> maneuverCandidates;
|
||||
|
||||
/**
|
||||
* The fix window consists of the list of fixes, a corresponding list with the course
|
||||
@@ -309,11 +317,17 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra
|
||||
this.track = track;
|
||||
this.boatClass = boatClass;
|
||||
this.fixWindow = new FixWindow();
|
||||
this.maneuverCandidates = new TreeSet<>(TimedComparator.INSTANCE);
|
||||
this.maneuverCandidates = Collections.synchronizedNavigableSet(new TreeSet<>(TimedComparator.INSTANCE));
|
||||
track.addListener(this);
|
||||
addAllFixesOfTrack();
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
synchronized (maneuverCandidates) {
|
||||
oos.defaultWriteObject();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void addAllFixesOfTrack() {
|
||||
track.lockForRead();
|
||||
try {
|
||||
@@ -424,7 +438,9 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra
|
||||
}
|
||||
}
|
||||
if (from.before(to)) {
|
||||
result = new ArrayList<>(maneuverCandidates.subSet(createDummyFix(from), /* fromInclusive */ true, createDummyFix(to), /* toInclusive */ true));
|
||||
synchronized (maneuverCandidates) {
|
||||
result = new ArrayList<>(maneuverCandidates.subSet(createDummyFix(from), /* fromInclusive */ true, createDummyFix(to), /* toInclusive */ true));
|
||||
}
|
||||
} else {
|
||||
result = Collections.emptySet();
|
||||
}
|
||||
|
||||
+3
@@ -77,6 +77,9 @@ public class BoatClassImageResolver {
|
||||
boatClassIconsMap.put(BoatClassMasterdata.HOBIE_TIGER.getDisplayName(), imageResources.HobieTigerIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.HOBIE_WILD_CAT.getDisplayName(), imageResources.HobieWildCatIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.INTERNATIONAL_14.getDisplayName(), imageResources.International14Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.IQFOIL_MEN.getDisplayName(), imageResources.IQFOilMenIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.IQFOIL_WOMEN.getDisplayName(), imageResources.IQFOilWoenIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.IQFOIL_YOUTH.getDisplayName(), imageResources.IQFOilYouthIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.J22.getDisplayName(), imageResources.J22Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.J24.getDisplayName(), imageResources.J24Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.J70.getDisplayName(), imageResources.J70Icon());
|
||||
|
||||
+12
@@ -396,6 +396,18 @@ public interface BoatClassImageResources extends ClientBundle {
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource International14Icon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/IQFOIL_MEN.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource IQFOilMenIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/IQFOIL_WOMEN.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource IQFOilWoenIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/IQFOIL_YOUTH.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource IQFOilYouthIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/OPEN_BIC.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource OpenBicIcon();
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ public class AbstractRegattaLogFixesAddMappingsDialog extends DataEntryDialog<Co
|
||||
sailingServiceWrite, stringMessages, errorReporter);
|
||||
boatTable = new BoatTableWrapper<RefreshableSingleSelectionModel<BoatDTO>>(sailingServiceWrite, userService,
|
||||
/* boatsRefresher not needed; registered boats taken from regatta log */ null,
|
||||
/* competitorsRefresher not neede */ null, stringMessages, errorReporter, /* multiSelection */ false,
|
||||
/* competitorsRefresher not needed */ null, stringMessages, errorReporter, /* multiSelection */ false,
|
||||
/* enable Pager */ true, /* allowActions */ false);
|
||||
|
||||
registerSelectionChangeHandler(competitorTable.getSelectionModel(), this::mappedToSelectionChanged);
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public abstract class AbstractRegattaLogSensorDataAddMappingsDialog extends Data
|
||||
event -> deviceSelectionChanged(deviceIdTable.getSelectionModel().getSelectedObject()));
|
||||
boatTable = new BoatTableWrapper<RefreshableSingleSelectionModel<BoatDTO>>(sailingServiceWrite, userService,
|
||||
/* boatsRefresher not needed; registrations are fetched for the leaderboard specifically */ null,
|
||||
/* competitorsRefresher not neede */ null,
|
||||
/* competitorsRefresher not needed */ null,
|
||||
stringMessages, errorReporter, /* multiSelection */ false, /* enable Pager */ true, /* allowActions */ false);
|
||||
competitorTable = new CompetitorTableWrapper<>(sailingServiceWrite, userService,
|
||||
/* competitorsRefresher not needed; registrations are fetched for the leaderboard specifically */ null,
|
||||
|
||||
+1
-1
@@ -283,7 +283,7 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
|
||||
sailingEventsListBox.addItem(stringMessages.selectSailingEvent(), stringMessages.selectSailingEvent());
|
||||
final Iterable<EventDTO> eventsSortedByName = Util.stream(existingEvents)
|
||||
.filter(event->userService.hasPermission(event, DefaultActions.UPDATE))
|
||||
.sorted(Util.naturalNamedComparator())::iterator;
|
||||
.sorted(Util.naturalNamedComparator(/* caseSensitive */ true))::iterator;
|
||||
for (EventDTO event : eventsSortedByName) {
|
||||
sailingEventsListBox.addItem(event.getName(), event.getId().toString());
|
||||
if (defaultEvent != null) {
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=Bredde (pixel)
|
||||
heightInPx=Højde (pixel)
|
||||
tags=Tags
|
||||
size=Størrelse
|
||||
duration=Varighed (t:mm:ss.ms)
|
||||
duration=Varighed (t:mm:ss)
|
||||
addMediaTrack=Tilføj lyd/video
|
||||
addYoutubeTrack=Tilføj Youtube
|
||||
youtubeId=Youtube-id
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=Ancho (píxeles)
|
||||
heightInPx=Alto (píxeles)
|
||||
tags=Etiquetas
|
||||
size=Tamaño
|
||||
duration=Duración (h:mm:ss.ms)
|
||||
duration=Duración (h:mm:ss)
|
||||
addMediaTrack=Añadir audio/vídeo
|
||||
addYoutubeTrack=Añadir Youtube
|
||||
youtubeId=ID de Youtube
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=Largeur (pixel)
|
||||
heightInPx=Hauteur (pixel)
|
||||
tags=Balises
|
||||
size=Taille
|
||||
duration=Durée (h:mm:ss.ms)
|
||||
duration=Durée (h:mm:ss)
|
||||
addMediaTrack=Ajouter audio/vidéo
|
||||
addYoutubeTrack=Ajouter Youtube
|
||||
youtubeId=ID Youtube
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=Larghezza (pixel)
|
||||
heightInPx=Altezza (pixel)
|
||||
tags=Tags
|
||||
size=Dimensione
|
||||
duration=Durata (h:mm:ss.ms)
|
||||
duration=Durata (h:mm:ss)
|
||||
addMediaTrack=Aggiungi audio/video
|
||||
addYoutubeTrack=Aggiungi Youtube
|
||||
youtubeId=ID Youtube
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=幅 (ピクセル)
|
||||
heightInPx=高さ (ピクセル)
|
||||
tags=タグ
|
||||
size=サイズ
|
||||
duration=時間 (h:mm:ss.ms)
|
||||
duration=時間 (h:mm:ss)
|
||||
addMediaTrack=音声/動画追加
|
||||
addYoutubeTrack=YouTube 追加
|
||||
youtubeId=YouTube ID
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=Largura (pixels)
|
||||
heightInPx=Altura (pixels)
|
||||
tags=Etiquetas
|
||||
size=Tamanho
|
||||
duration=Duração (h:mm:ss.ms)
|
||||
duration=Duração (h:mm:ss)
|
||||
addMediaTrack=Adicionar áudio/vídeo
|
||||
addYoutubeTrack=Adicionar Youtube
|
||||
youtubeId=ID do Youtube
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=Ширина (в пикселях)
|
||||
heightInPx=Высота (в пикселях)
|
||||
tags=Теги
|
||||
size=Размер
|
||||
duration=Длительность (ч:мм:сс.мс)
|
||||
duration=Длительность (ч:мм:сс)
|
||||
addMediaTrack=Добавить аудио/видео
|
||||
addYoutubeTrack=Добавить Youtube
|
||||
youtubeId=Ид. Youtube
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=Širina (slikovne pike)
|
||||
heightInPx=Višina (slikovne pike)
|
||||
tags=Oznake
|
||||
size=Velikost
|
||||
duration=Trajanje (h:mm:ss.ms)
|
||||
duration=Trajanje (h:mm:ss)
|
||||
addMediaTrack=Dodaj zvok/video
|
||||
addYoutubeTrack=Dodaj Youtube
|
||||
youtubeId=ID za Youtube
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ widthInPx=宽度(像素)
|
||||
heightInPx=高度(像素)
|
||||
tags=标记
|
||||
size=大小
|
||||
duration=持续时间 (h:mm:ss.ms)
|
||||
duration=持续时间 (h:mm:ss)
|
||||
addMediaTrack=添加音频/视频
|
||||
addYoutubeTrack=添加 Youtube
|
||||
youtubeId=Youtube 编号
|
||||
|
||||
+1
@@ -31,6 +31,7 @@ public class BoatClassVectorGraphicsResolver {
|
||||
BoatClassMasterdata.FINN, BoatClassMasterdata.MUSTO_SKIFF, BoatClassMasterdata.OPEN_BIC,
|
||||
BoatClassMasterdata.OPTIMIST, BoatClassMasterdata.PWA,
|
||||
BoatClassMasterdata.RS_AERO, BoatClassMasterdata.RS_X,
|
||||
BoatClassMasterdata.IQFOIL_MEN, BoatClassMasterdata.IQFOIL_WOMEN, BoatClassMasterdata.IQFOIL_YOUTH,
|
||||
BoatClassMasterdata.SPLASH_BLUE, BoatClassMasterdata.SPLASH_RED, BoatClassMasterdata.SPLASH_GREEN,
|
||||
BoatClassMasterdata.STAR, BoatClassMasterdata.TECHNO_293, BoatClassMasterdata.TECHNO_293_PLUS);
|
||||
BoatClassVectorGraphics _49er = new _49erVectorGraphics(BoatClassMasterdata._49ER, BoatClassMasterdata._49ERFX,
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -1,5 +1,4 @@
|
||||
DELETE FROM SAILING."CompetitorRace" CASCADE;
|
||||
DELETE FROM SAILING."Event" CASCADE;
|
||||
DELETE FROM SAILING."RaceResult" CASCADE;
|
||||
DELETE FROM SAILING."RaceStats" CASCADE;
|
||||
DELETE FROM SAILING."Leg" CASCADE;
|
||||
@@ -7,6 +6,7 @@ DELETE FROM SAILING."LegStats" CASCADE;
|
||||
DELETE FROM SAILING."Maneuver" CASCADE;
|
||||
DELETE FROM SAILING."Race" CASCADE;
|
||||
DELETE FROM SAILING."Regatta" CASCADE;
|
||||
DELETE FROM SAILING."Event" CASCADE;
|
||||
DELETE FROM SAILING."Competitor" CASCADE;
|
||||
DELETE FROM SAILING."BoatClass" CASCADE;
|
||||
DELETE FROM SAILING."IRM" CASCADE;
|
||||
|
||||
@@ -6,7 +6,7 @@ CREATE COLUMN TABLE SAILING."Event" (
|
||||
"venue" NVARCHAR(255),
|
||||
"isListed" BOOLEAN,
|
||||
"description" NVARCHAR(5000),
|
||||
"location" ST_POINT
|
||||
"location" ST_POINT(3857)
|
||||
);
|
||||
CREATE ROW TABLE SAILING."ScoringScheme" (
|
||||
"id" NVARCHAR(255) PRIMARY KEY,
|
||||
@@ -49,14 +49,14 @@ CREATE COLUMN TABLE SAILING."Race" (
|
||||
FOREIGN KEY ("regatta") REFERENCES SAILING."Regatta" ("name")
|
||||
);
|
||||
CREATE TABLE SAILING."Competitor" (
|
||||
"id" NVARCHAR(36) PRIMARY KEY,
|
||||
"id" NVARCHAR(255) PRIMARY KEY,
|
||||
"name" NVARCHAR(255) NOT NULL,
|
||||
"shortName" NVARCHAR(20),
|
||||
"nationality" NVARCHAR(3) NOT NULL,
|
||||
"sailNumber" NVARCHAR(255)
|
||||
);
|
||||
CREATE TABLE SAILING."CompetitorRace" (
|
||||
"competitorId" NVARCHAR(36),
|
||||
"competitorId" NVARCHAR(255),
|
||||
"race" NVARCHAR(255),
|
||||
"regatta" NVARCHAR(255),
|
||||
PRIMARY KEY ("competitorId", "race"),
|
||||
@@ -66,7 +66,7 @@ CREATE TABLE SAILING."CompetitorRace" (
|
||||
CREATE TABLE SAILING."RaceResult" (
|
||||
"regatta" NVARCHAR(255) NOT NULL,
|
||||
"raceColumn" NVARCHAR(255) NOT NULL,
|
||||
"competitorId" NVARCHAR(36) NOT NULL,
|
||||
"competitorId" NVARCHAR(255) NOT NULL,
|
||||
"points" DOUBLE,
|
||||
"discarded" BOOLEAN,
|
||||
"irm" NVARCHAR(4),
|
||||
@@ -76,7 +76,7 @@ CREATE TABLE SAILING."RaceResult" (
|
||||
CREATE TABLE SAILING."RaceStats" (
|
||||
"race" NVARCHAR(255) NOT NULL,
|
||||
"regatta" NVARCHAR(255) NOT NULL,
|
||||
"competitorId" NVARCHAR(36) NOT NULL,
|
||||
"competitorId" NVARCHAR(255) NOT NULL,
|
||||
"rankOneBased" INTEGER,
|
||||
"distanceSailedInMeters" DOUBLE,
|
||||
"elapsedTimeInSeconds" DOUBLE,
|
||||
@@ -105,7 +105,7 @@ CREATE TABLE SAILING."LegStats" (
|
||||
"race" NVARCHAR(255) NOT NULL,
|
||||
"regatta" NVARCHAR(255) NOT NULL,
|
||||
"number" INTEGER NOT NULL,
|
||||
"competitorId" NVARCHAR(36) NOT NULL,
|
||||
"competitorId" NVARCHAR(255) NOT NULL,
|
||||
"rankOneBased" INTEGER,
|
||||
"distanceSailedInMeters" DOUBLE,
|
||||
"elapsedTimeInSeconds" DOUBLE,
|
||||
@@ -123,7 +123,7 @@ CREATE TABLE SAILING."LegStats" (
|
||||
CREATE TABLE SAILING."Maneuver" (
|
||||
"race" NVARCHAR(255) NOT NULL,
|
||||
"regatta" NVARCHAR(255) NOT NULL,
|
||||
"competitorId" NVARCHAR(36) NOT NULL,
|
||||
"competitorId" NVARCHAR(255) NOT NULL,
|
||||
"timepoint" TIMESTAMP NOT NULL,
|
||||
"type" NVARCHAR(20) NOT NULL,
|
||||
"newTack" NVARCHAR(20),
|
||||
|
||||
+2
-1
@@ -2,11 +2,12 @@ package com.sap.sailing.hanaexport;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.sap.sailing.hanaexport.impl.HanaConnectionFactoryImpl;
|
||||
|
||||
public interface HanaConnectionFactory {
|
||||
static HanaConnectionFactory INSTANCE = new HanaConnectionFactoryImpl();
|
||||
|
||||
Connection getConnection() throws SQLException;
|
||||
Connection getConnection(Optional<String> dbEndpoint, Optional<String> dbUser, Optional<String> dbPassword) throws SQLException;
|
||||
}
|
||||
|
||||
+28
-5
@@ -6,6 +6,7 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.common.BoatClassMasterdata;
|
||||
@@ -20,7 +21,7 @@ public class HanaConnectionFactoryImpl implements HanaConnectionFactory {
|
||||
public void test() throws SQLException {
|
||||
System.out.println("Java version: " + com.sap.db.jdbc.Driver.getJavaVersion());
|
||||
System.out.println("Minimum supported Java version and SAP driver version number: " + com.sap.db.jdbc.Driver.getVersionInfo());
|
||||
final Connection connection = getConnection();
|
||||
final Connection connection = getConnection(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
if (connection == null) {
|
||||
logger.warning("Couldn't get database connection for end point "+System.getProperty(HANADB_ENDPOINT_PROPERTY_NAME));
|
||||
} else {
|
||||
@@ -42,11 +43,33 @@ public class HanaConnectionFactoryImpl implements HanaConnectionFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
public Connection getConnection(Optional<String> dbEndpoint, Optional<String> dbUser, Optional<String> dbPassword) throws SQLException {
|
||||
final String dbEndpointFromSystemProperty = System.getProperty(HANADB_ENDPOINT_PROPERTY_NAME);
|
||||
final String dbUserFromSystemProperty = System.getProperty(HANADB_USERNAME_SYSTEM_PROPERTY_NAME);
|
||||
final String dbPasswordFromSystemProperty = System.getProperty(HANADB_PASSWORD_SYSTEM_PROPERTY_NAME);
|
||||
final String dbUrl = "jdbc:sap://"+dbEndpoint.orElseGet(()->{
|
||||
if (dbEndpointFromSystemProperty != null) {
|
||||
return dbEndpointFromSystemProperty;
|
||||
} else {
|
||||
throw new IllegalStateException("Missing DB URL, either as parameter or from system property "+HANADB_ENDPOINT_PROPERTY_NAME);
|
||||
}
|
||||
});
|
||||
return DriverManager.getConnection(
|
||||
"jdbc:sap://"+System.getProperty(HANADB_ENDPOINT_PROPERTY_NAME)+"/?encrypt=true&validateCertificate=false",
|
||||
System.getProperty(HANADB_USERNAME_SYSTEM_PROPERTY_NAME),
|
||||
System.getProperty(HANADB_PASSWORD_SYSTEM_PROPERTY_NAME));
|
||||
dbUrl,
|
||||
dbUser.orElseGet(()->{
|
||||
if (dbUserFromSystemProperty != null) {
|
||||
return dbUserFromSystemProperty;
|
||||
} else {
|
||||
throw new IllegalStateException("Missing DB user name, either as parameter or from system property "+HANADB_USERNAME_SYSTEM_PROPERTY_NAME);
|
||||
}
|
||||
}),
|
||||
dbPassword.orElseGet(()->{
|
||||
if (dbPasswordFromSystemProperty != null) {
|
||||
return dbPasswordFromSystemProperty;
|
||||
} else {
|
||||
throw new IllegalStateException("Missing DB password, either as parameter or from system property "+HANADB_PASSWORD_SYSTEM_PROPERTY_NAME);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws SQLException {
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
public abstract class AbstractPreparedInsertStatement<T> implements PreparedInsertStatement<T> {
|
||||
private final PreparedStatement preparedStatement;
|
||||
|
||||
protected AbstractPreparedInsertStatement(PreparedStatement preparedStatement) {
|
||||
this.preparedStatement = preparedStatement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement getPreparedStatement() {
|
||||
return preparedStatement;
|
||||
}
|
||||
|
||||
protected void setDouble(int parameterIndex, double value) throws SQLException {
|
||||
if (Double.isNaN(value) || Double.isInfinite(value)) {
|
||||
setDouble(parameterIndex, 0.0);
|
||||
} else {
|
||||
getPreparedStatement().setDouble(parameterIndex, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected int intOr0ForNull(Integer i) {
|
||||
return i==null?0:i;
|
||||
}
|
||||
|
||||
protected double metersOr0ForNull(final Distance distance) {
|
||||
return distance == null ? 0 : distance.getMeters();
|
||||
}
|
||||
|
||||
protected double secondsOr0ForNull(final Duration duration) {
|
||||
return duration == null ? 0 : duration.asSeconds();
|
||||
}
|
||||
}
|
||||
+156
-343
@@ -3,14 +3,18 @@ package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Date;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
@@ -20,40 +24,30 @@ import javax.ws.rs.core.Response;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.SpeedWithConfidence;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache;
|
||||
import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||
import com.sap.sailing.hanaexport.HanaConnectionFactory;
|
||||
import com.sap.sailing.hanaexport.jaxrs.api.InsertRegattaStatement.RegattaAndEvent;
|
||||
import com.sap.sailing.server.interfaces.RacingEventService;
|
||||
import com.sap.sailing.shared.server.gateway.jaxrs.SharedAbstractSailingServerResource;
|
||||
import com.sap.sse.ServerInfo;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
|
||||
@@ -63,37 +57,72 @@ import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
public class HanaCloudSacExportResource extends SharedAbstractSailingServerResource {
|
||||
private static final Logger logger = Logger.getLogger(HanaCloudSacExportResource.class.getName());
|
||||
|
||||
private class AlreadyInsertedContent {
|
||||
private final Set<Event> events;
|
||||
private final Set<Competitor> competitors;
|
||||
private final InsertCompetitorStatement insertCompetitors;
|
||||
private final InsertEventStatement insertEvents;
|
||||
public AlreadyInsertedContent(InsertEventStatement insertEvents, InsertCompetitorStatement insertCompetitors) {
|
||||
events = new HashSet<>();
|
||||
competitors = new HashSet<>();
|
||||
this.insertEvents = insertEvents;
|
||||
this.insertCompetitors = insertCompetitors;
|
||||
}
|
||||
|
||||
public void ensureEventIsInserted(Event event) throws SQLException {
|
||||
if (!events.contains(event)) {
|
||||
events.add(event);
|
||||
insertEvents.insert(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void ensureCompetitorIsInserted(Competitor competitor) throws SQLException {
|
||||
if (!competitors.contains(competitor)) {
|
||||
competitors.add(competitor);
|
||||
insertCompetitors.insert(competitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Produces("application/json;charset=UTF-8")
|
||||
@Path("clear")
|
||||
public Response clear() throws SQLException, IOException {
|
||||
public Response clear(
|
||||
@FormParam("dbendpoint") String dbEndpoint,
|
||||
@FormParam("dbuser") String dbUser,
|
||||
@FormParam("dbpassword") String dbPassword) throws SQLException, IOException {
|
||||
SecurityUtils.getSubject().checkPermission(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
SecuredSecurityTypes.ServerActions.CAN_EXPORT_MASTERDATA,
|
||||
new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
logger.info("Clearing HANA Cloud SAILING DB on behalf of user "+SecurityUtils.getSubject().getPrincipal());
|
||||
final Connection connection = HanaConnectionFactory.INSTANCE.getConnection();
|
||||
final Connection connection = HanaConnectionFactory.INSTANCE.getConnection(Optional.ofNullable(dbEndpoint),
|
||||
Optional.ofNullable(dbUser), Optional.ofNullable(dbPassword));
|
||||
tryExecutingQueriesFromSqlResource("/cleartables.sql", connection);
|
||||
logger.info("Done learing HANA Cloud SAILING DB on behalf of user "+SecurityUtils.getSubject().getPrincipal());
|
||||
logger.info("Done clearing HANA Cloud SAILING DB on behalf of user "+SecurityUtils.getSubject().getPrincipal());
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Produces("application/json;charset=UTF-8")
|
||||
@Path("export")
|
||||
public Response export() throws SQLException {
|
||||
public Response export(@QueryParam("leaderboardgroupid") List<String> leaderboardGroupIds,
|
||||
@QueryParam("eventid") List<String> eventIds,
|
||||
@FormParam("dbendpoint") String dbEndpoint,
|
||||
@FormParam("dbuser") String dbUser,
|
||||
@FormParam("dbpassword") String dbPassword) throws SQLException {
|
||||
SecurityUtils.getSubject().checkPermission(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
SecuredSecurityTypes.ServerActions.CAN_EXPORT_MASTERDATA,
|
||||
new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
logger.info("Exporting HANA Cloud SAILING DB content on behalf of user "+SecurityUtils.getSubject().getPrincipal());
|
||||
final RacingEventService racingEventService = getService();
|
||||
try {
|
||||
final Connection connection = HanaConnectionFactory.INSTANCE.getConnection();
|
||||
final Connection connection = HanaConnectionFactory.INSTANCE.getConnection(Optional.ofNullable(dbEndpoint),
|
||||
Optional.ofNullable(dbUser), Optional.ofNullable(dbPassword));
|
||||
exportBoatClasses(racingEventService, connection);
|
||||
exportIrms(racingEventService, connection);
|
||||
exportScoringSchemes(racingEventService, connection);
|
||||
exportCompetitors(racingEventService, connection);
|
||||
exportEvents(racingEventService, connection);
|
||||
exportRaces(racingEventService, connection);
|
||||
final Iterable<Regatta> regattasToExport = getRegattasToExport(racingEventService, leaderboardGroupIds, eventIds);
|
||||
exportRaces(racingEventService, regattasToExport, connection);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Problem exporting data to HANA", e);
|
||||
throw e;
|
||||
@@ -102,356 +131,148 @@ public class HanaCloudSacExportResource extends SharedAbstractSailingServerResou
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
private void exportCompetitors(RacingEventService racingEventService, Connection connection) throws SQLException {
|
||||
final PreparedStatement insertCompetitors = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Competitor\" (\"id\", \"name\", \"shortName\", \"nationality\", \"sailNumber\") VALUES (?, ?, ?, ?, ?);");
|
||||
for (final Competitor competitor : racingEventService.getCompetitorAndBoatStore().getAllCompetitors()) {
|
||||
insertCompetitors.setString(1, competitor.getId().toString());
|
||||
insertCompetitors.setString(2, competitor.getName());
|
||||
insertCompetitors.setString(3, competitor.getShortName());
|
||||
insertCompetitors.setString(4, competitor.getNationality() == null ? " " : competitor.getNationality().getThreeLetterIOCAcronym());
|
||||
insertCompetitors.setString(5, competitor.hasBoat() ? ((CompetitorWithBoat) competitor).getBoat().getSailID() : null);
|
||||
insertCompetitors.execute();
|
||||
private Iterable<Regatta> getRegattasToExport(RacingEventService racingEventService, List<String> leaderboardGroupIds, List<String> eventIds) {
|
||||
final Set<LeaderboardGroup> leaderboardGroups = new HashSet<>();
|
||||
final Iterable<Regatta> result;
|
||||
boolean atLeastOneIdProvided = false;
|
||||
if (leaderboardGroupIds != null) {
|
||||
for (final String leaderboardGroupIdAsString : leaderboardGroupIds) {
|
||||
atLeastOneIdProvided = true;
|
||||
try {
|
||||
leaderboardGroups.add(racingEventService.getLeaderboardGroupByID(UUID.fromString(leaderboardGroupIdAsString)));
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.log(Level.WARNING, "Couldn't parse "+leaderboardGroupIdAsString+" as a leaderboard group's UUID. Ignoring.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (eventIds != null) {
|
||||
for (final String eventIdAsString : eventIds) {
|
||||
atLeastOneIdProvided = true;
|
||||
try {
|
||||
final Event event = racingEventService.getEvent(UUID.fromString(eventIdAsString));
|
||||
Util.addAll(event.getLeaderboardGroups(), leaderboardGroups);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.log(Level.WARNING, "Couldn't parse "+eventIdAsString+" as an event's UUID. Ignoring.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (atLeastOneIdProvided) {
|
||||
final Set<Regatta> resultSet = new HashSet<>();
|
||||
for (final LeaderboardGroup leaderboardGroup : leaderboardGroups) {
|
||||
for (final Leaderboard leaderboard : leaderboardGroup.getLeaderboards()) {
|
||||
if (leaderboard.getLeaderboardType().isRegattaLeaderboard()) {
|
||||
resultSet.add(((RegattaLeaderboard) leaderboard).getRegatta());
|
||||
}
|
||||
}
|
||||
}
|
||||
result = resultSet;
|
||||
} else {
|
||||
result = racingEventService.getAllRegattas();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void exportIrms(RacingEventService racingEventService, Connection connection) throws SQLException {
|
||||
final PreparedStatement insertBoatClasses = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"IRM\" (\"name\", \"discardable\", \"advanceCompetitorsTrackedWorse\", \"appliesAtStartOfRace\") VALUES (?, ?, ?, ?);");
|
||||
for (final MaxPointsReason irm : MaxPointsReason.values()) {
|
||||
insertBoatClasses.setString(1, irm.name());
|
||||
insertBoatClasses.setBoolean(2, irm.isDiscardable());
|
||||
insertBoatClasses.setBoolean(3, irm.isAdvanceCompetitorsTrackedWorse());
|
||||
insertBoatClasses.setBoolean(4, irm.isAppliesAtStartOfRace());
|
||||
insertBoatClasses.execute();
|
||||
}
|
||||
final InsertIrmStatement insertIrms = new InsertIrmStatement(connection);
|
||||
insertIrms.insertBatch(Arrays.asList(MaxPointsReason.values()));
|
||||
insertIrms.executeBatch();
|
||||
}
|
||||
|
||||
private void exportScoringSchemes(RacingEventService racingEventService, Connection connection) throws SQLException {
|
||||
final PreparedStatement insertBoatClasses = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"ScoringScheme\" (\"id\", \"higherIsBetter\") VALUES (?, ?);");
|
||||
final InsertScoringSchemeStatement insertScoringScheme = new InsertScoringSchemeStatement(connection);
|
||||
for (final ScoringSchemeType scoringSchemeType : ScoringSchemeType.values()) {
|
||||
final ScoringScheme scoringScheme = racingEventService.getBaseDomainFactory().createScoringScheme(scoringSchemeType);
|
||||
insertBoatClasses.setString(1, scoringScheme.getType().name());
|
||||
insertBoatClasses.setBoolean(2, scoringScheme.isHigherBetter());
|
||||
insertBoatClasses.execute();
|
||||
insertScoringScheme.insertBatch(scoringScheme);
|
||||
}
|
||||
insertScoringScheme.executeBatch();
|
||||
}
|
||||
|
||||
private void exportBoatClasses(final RacingEventService racingEventService, final Connection connection)
|
||||
throws SQLException {
|
||||
final PreparedStatement insertBoatClasses = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"BoatClass\" (\"id\", \"description\", \"hullLengthInMeters\", \"hullBeamInMeters\", \"hullType\") VALUES (?, ?, ?, ?, ?);");
|
||||
for (final BoatClass boatClass : racingEventService.getBaseDomainFactory().getBoatClasses()) {
|
||||
if (boatClass.getName() == null) {
|
||||
insertBoatClasses.setString(1, "<null>");
|
||||
} else {
|
||||
insertBoatClasses.setString(1, boatClass.getName().substring(0, Math.min(boatClass.getName().length(), 255)));
|
||||
}
|
||||
insertBoatClasses.setString(2, "Type "+boatClass.getHullType().name()+", length "+
|
||||
boatClass.getHullLength().getMeters()+"m, beam "+boatClass.getHullBeam().getMeters()+"m");
|
||||
setDouble(insertBoatClasses, 3, boatClass.getHullLength().getMeters());
|
||||
setDouble(insertBoatClasses, 4, boatClass.getHullBeam().getMeters());
|
||||
insertBoatClasses.setString(5, boatClass.getHullType().name());
|
||||
insertBoatClasses.execute();
|
||||
}
|
||||
final InsertBoatClassStatement insertBoatClasses = new InsertBoatClassStatement(connection);
|
||||
insertBoatClasses.insertBatch(racingEventService.getBaseDomainFactory().getBoatClasses());
|
||||
insertBoatClasses.executeBatch();
|
||||
}
|
||||
|
||||
private void exportEvents(RacingEventService racingEventService, Connection connection) throws SQLException {
|
||||
final PreparedStatement insertEvents = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Event\" (\"id\", \"name\", \"startDate\", \"endDate\", \"venue\", \"isListed\", \"description\", \"location\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, NEW ST_POINT(?));");
|
||||
for (final Event event : racingEventService.getAllEvents()) {
|
||||
insertEvents.setString(1, event.getId().toString());
|
||||
insertEvents.setString(2, event.getName());
|
||||
insertEvents.setDate(3, event.getStartDate()==null?null:new Date(event.getStartDate().asMillis()));
|
||||
insertEvents.setDate(4, event.getEndDate()==null?null:new Date(event.getEndDate().asMillis()));
|
||||
insertEvents.setString(5, event.getVenue().getName());
|
||||
insertEvents.setBoolean(6, event.isPublic());
|
||||
insertEvents.setString(7, event.getDescription());
|
||||
final Position location = event.getLocation();
|
||||
insertEvents.setString(8, location != null ? String.format("POINT(%1.5f %1.5f)", location.getLatDeg(), location.getLngDeg()) : null);
|
||||
insertEvents.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void exportRaces(RacingEventService racingEventService, Connection connection) throws SQLException {
|
||||
private void exportRaces(RacingEventService racingEventService, Iterable<Regatta> regattasToExport, Connection connection) throws SQLException {
|
||||
final TimePoint now = TimePoint.now();
|
||||
final PreparedStatement insertRegattas = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Regatta\" (\"name\", \"boatClass\", \"scoringScheme\", \"rankingMetric\", \"eventId\") "+
|
||||
"VALUES (?, ?, ?, ?, ?);");
|
||||
final PreparedStatement insertRaces = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Race\" (\"name\", \"regatta\", \"raceColumn\", \"fleet\", \"startOfTracking\", "+
|
||||
"\"startOfRace\", \"endOfTracking\", \"endOfRace\", \"avgWindSpeedInKnots\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||
final PreparedStatement insertRaceResults = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"RaceResult\" (\"regatta\", \"raceColumn\", \"competitorId\", \"points\", "+
|
||||
"\"discarded\", \"irm\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?);");
|
||||
final PreparedStatement insertRaceStats = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"RaceStats\" (\"race\", \"regatta\", \"competitorId\", \"rankOneBased\", \"distanceSailedInMeters\", \"elapsedTimeInSeconds\", "+
|
||||
"\"avgCrossTrackErrorInMeters\", \"absoluteAvgCrossTrackErrorInMeters\", \"numberOfTacks\", "+
|
||||
"\"numberOfGybes\", \"numberOfPenaltyCircles\", \"startDelayInSeconds\", \"distanceFromStartLineInMetersAtStart\", "+
|
||||
"\"speedWhenCrossingStartLineInKnots\", \"startTack\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||
final PreparedStatement insertLegs = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Leg\" (\"race\", \"regatta\", \"number\", \"type\") "+
|
||||
"VALUES (?, ?, ?, ?);");
|
||||
final PreparedStatement insertLegStats = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"LegStats\" (\"race\", \"regatta\", \"number\", \"competitorId\", \"rankOneBased\", \"distanceSailedInMeters\", \"elapsedTimeInSeconds\", "+
|
||||
"\"avgCrossTrackErrorInMeters\", \"absoluteAvgCrossTrackErrorInMeters\", \"numberOfTacks\", "+
|
||||
"\"numberOfGybes\", \"numberOfPenaltyCircles\", \"avgVelocityMadeGoodInKnots\", \"gapToLeaderInSeconds\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||
final PreparedStatement insertManeuvers = connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Maneuver\" (\"race\", \"regatta\", \"competitorId\", \"timepoint\", \"type\", \"newTack\", "+
|
||||
"\"lossInMeters\", \"speedBeforeInKnots\", \"speedAfterInKnots\", "+
|
||||
"\"courseBeforeInTrueDegrees\", \"courseAfterInTrueDegrees\", \"directionChangeInDegrees\", \"maximumTurningRateInDegreesPerSecond\", "+
|
||||
"\"lowestSpeedInKnots\", \"toSide\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||
for (final Regatta regatta : racingEventService.getAllRegattas()) {
|
||||
final InsertEventStatement insertEvents = new InsertEventStatement(connection);
|
||||
final InsertCompetitorStatement insertCompetitors = new InsertCompetitorStatement(connection);
|
||||
final AlreadyInsertedContent alreadyInsertedContent = new AlreadyInsertedContent(insertEvents, insertCompetitors);
|
||||
final InsertRegattaStatement insertRegattas = new InsertRegattaStatement(connection);
|
||||
final InsertRaceStatement insertRaces = new InsertRaceStatement(connection);
|
||||
final InsertRaceResultStatement insertRaceResults = new InsertRaceResultStatement(connection);
|
||||
final InsertRaceStatsStatement insertRaceStats = new InsertRaceStatsStatement(connection);
|
||||
final InsertLegStatement insertLegs = new InsertLegStatement(connection);
|
||||
final InsertLegStatsStatement insertLegStats = new InsertLegStatsStatement(connection);
|
||||
final InsertManeuverStatement insertManeuvers = new InsertManeuverStatement(connection);
|
||||
for (final Regatta regatta : regattasToExport) {
|
||||
final Leaderboard leaderboard = racingEventService.getLeaderboardByName(regatta.getName());
|
||||
if (leaderboard != null) {
|
||||
final Event event = racingEventService.findEventContainingLeaderboardAndMatchingAtLeastOneCourseArea(leaderboard);
|
||||
insertRegattas.setString(1, regatta.getName());
|
||||
insertRegattas.setString(2, regatta.getBoatClass().getName());
|
||||
insertRegattas.setString(3, regatta.getScoringScheme().getType().name());
|
||||
insertRegattas.setString(4, regatta.getRankingMetricType().name());
|
||||
insertRegattas.setString(5, event == null ? null : event.getId().toString());
|
||||
insertRegattas.execute();
|
||||
if (leaderboard != null) {
|
||||
for (final RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
for (final Competitor competitor : raceColumn.getAllCompetitors()) {
|
||||
parameterizeInsertRaceResult(insertRaceResults, now, competitor, leaderboard, raceColumn, regatta);
|
||||
insertRaceResults.addBatch();
|
||||
}
|
||||
insertRaceResults.executeBatch();
|
||||
for (final Fleet fleet : raceColumn.getFleets()) {
|
||||
final TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
if (trackedRace != null) {
|
||||
final RankingInfo rankingInfo = trackedRace.getRankingMetric().getRankingInfo(now);
|
||||
final WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache = new LeaderboardDTOCalculationReuseCache(now);
|
||||
parameterizeInsertRacesStatement(insertRaces, regatta, raceColumn, fleet, trackedRace);
|
||||
insertRaces.addBatch();
|
||||
for (final TrackedLeg trackedLeg : trackedRace.getTrackedLegs()) {
|
||||
parameterizeInsertLegsStatement(insertLegs, now, regatta, trackedRace, trackedLeg);
|
||||
insertLegs.addBatch();
|
||||
for (final Competitor competitor : trackedRace.getRace().getCompetitors()) {
|
||||
parameterizeInsertLegStatsStatement(insertLegStats, now, trackedLeg.getTrackedLeg(competitor), rankingInfo, cache);
|
||||
insertLegStats.addBatch();
|
||||
}
|
||||
}
|
||||
if (event != null) {
|
||||
alreadyInsertedContent.ensureEventIsInserted(event);
|
||||
insertRegattas.insert(new RegattaAndEvent(regatta, event));
|
||||
if (leaderboard != null) {
|
||||
for (final RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
for (final Competitor competitor : raceColumn.getAllCompetitors()) {
|
||||
alreadyInsertedContent.ensureCompetitorIsInserted(competitor);
|
||||
insertRaceResults.insertBatch(new InsertRaceResultStatement.RaceResult(regatta, leaderboard, competitor, raceColumn, now));
|
||||
}
|
||||
final Waypoint startWaypoint = trackedRace == null ? null : trackedRace.getRace().getCourse().getFirstWaypoint();
|
||||
if (trackedRace != null) {
|
||||
for (final Competitor competitor : trackedRace.getRace().getCompetitors()) {
|
||||
parameterizeInsertRaceStats(insertRaceStats, now, startWaypoint, competitor, trackedRace);
|
||||
insertRaceStats.addBatch();
|
||||
final LinkedHashMap<TimePoint, Maneuver> timepointUniqueManeuvers = new LinkedHashMap<>();
|
||||
for (final Maneuver maneuver : trackedRace.getManeuvers(competitor, /* waitForLatest */ false)) {
|
||||
if (maneuver.getType() == ManeuverType.TACK || maneuver.getType() == ManeuverType.JIBE || maneuver.getType() == ManeuverType.PENALTY_CIRCLE) {
|
||||
timepointUniqueManeuvers.put(maneuver.getTimePoint(), maneuver);
|
||||
insertRaceResults.executeBatch();
|
||||
for (final Fleet fleet : raceColumn.getFleets()) {
|
||||
final TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
if (trackedRace != null) {
|
||||
final RankingInfo rankingInfo = trackedRace.getRankingMetric().getRankingInfo(now);
|
||||
final WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache = new LeaderboardDTOCalculationReuseCache(now);
|
||||
insertRaces.insertBatch(new InsertRaceStatement.TrackedRaceWithRaceColumnAndFleet(trackedRace, raceColumn, fleet));
|
||||
for (final TrackedLeg trackedLeg : trackedRace.getTrackedLegs()) {
|
||||
insertLegs.insertBatch(new InsertLegStatement.TrackedLegAndNow(now, trackedLeg));
|
||||
for (final Competitor competitor : trackedRace.getRace().getCompetitors()) {
|
||||
insertLegStats.insertBatch(new InsertLegStatsStatement.TrackedLegOfCompetitorRankingInfoCacheAndNow(now, rankingInfo, cache, trackedLeg.getTrackedLeg(competitor)));
|
||||
}
|
||||
}
|
||||
for (final Maneuver maneuver : timepointUniqueManeuvers.values()) {
|
||||
parameterizeInsertManeuvers(insertManeuvers, competitor, maneuver, trackedRace);
|
||||
insertManeuvers.addBatch();
|
||||
}
|
||||
final Waypoint startWaypoint = trackedRace == null ? null : trackedRace.getRace().getCourse().getFirstWaypoint();
|
||||
if (trackedRace != null) {
|
||||
for (final Competitor competitor : trackedRace.getRace().getCompetitors()) {
|
||||
insertRaceStats.insertBatch(new InsertRaceStatsStatement.TrackedRaceWithCompetitorAndStartWaypoint(now, startWaypoint, competitor, trackedRace));
|
||||
final LinkedHashMap<TimePoint, Maneuver> timepointUniqueManeuvers = new LinkedHashMap<>();
|
||||
for (final Maneuver maneuver : trackedRace.getManeuvers(competitor, /* waitForLatest */ false)) {
|
||||
if (maneuver.getType() == ManeuverType.TACK || maneuver.getType() == ManeuverType.JIBE || maneuver.getType() == ManeuverType.PENALTY_CIRCLE) {
|
||||
timepointUniqueManeuvers.put(maneuver.getTimePoint(), maneuver);
|
||||
}
|
||||
}
|
||||
for (final Maneuver maneuver : timepointUniqueManeuvers.values()) {
|
||||
insertManeuvers.insertBatch(new InsertManeuverStatement.ManeuverTrackedRaceAndCompetitor(maneuver, trackedRace, competitor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
insertRaces.executeBatch();
|
||||
insertLegs.executeBatch();
|
||||
insertLegStats.executeBatch();
|
||||
insertRaceStats.executeBatch();
|
||||
insertManeuvers.executeBatch();
|
||||
}
|
||||
insertRaces.executeBatch();
|
||||
insertLegs.executeBatch();
|
||||
insertLegStats.executeBatch();
|
||||
insertRaceStats.executeBatch();
|
||||
insertManeuvers.executeBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parameterizeInsertManeuvers(PreparedStatement insertManeuvers, Competitor competitor, Maneuver maneuver, TrackedRace trackedRace) throws SQLException {
|
||||
insertManeuvers.setString(1, trackedRace.getRace().getName());
|
||||
insertManeuvers.setString(2, trackedRace.getTrackedRegatta().getRegatta().getName());
|
||||
insertManeuvers.setString(3, competitor.getId().toString());
|
||||
insertManeuvers.setDate(4, new Date(maneuver.getTimePoint().asMillis()));
|
||||
insertManeuvers.setString(5, maneuver.getType().name());
|
||||
insertManeuvers.setString(6, maneuver.getNewTack().name());
|
||||
if (maneuver.getManeuverLoss() != null) {
|
||||
setDouble(insertManeuvers, 7,
|
||||
maneuver.getManeuverLoss().getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters()
|
||||
-maneuver.getManeuverLoss().getDistanceSailedProjectedOnMiddleManeuverAngle().getMeters());
|
||||
} else {
|
||||
setDouble(insertManeuvers, 7, 0);
|
||||
}
|
||||
setDouble(insertManeuvers, 8, maneuver.getSpeedWithBearingBefore().getKnots());
|
||||
setDouble(insertManeuvers, 9, maneuver.getSpeedWithBearingAfter().getKnots());
|
||||
setDouble(insertManeuvers, 10, maneuver.getSpeedWithBearingBefore().getBearing().getDegrees());
|
||||
setDouble(insertManeuvers, 11, maneuver.getSpeedWithBearingAfter().getBearing().getDegrees());
|
||||
setDouble(insertManeuvers, 12, maneuver.getDirectionChangeInDegrees());
|
||||
setDouble(insertManeuvers, 13, maneuver.getMaxTurningRateInDegreesPerSecond());
|
||||
setDouble(insertManeuvers, 14, maneuver.getLowestSpeed().getKnots());
|
||||
insertManeuvers.setString(15, maneuver.getToSide().name());
|
||||
}
|
||||
|
||||
private void parameterizeInsertLegStatsStatement(PreparedStatement insertLegStats, TimePoint now,
|
||||
TrackedLegOfCompetitor trackedLegOfCompetitor, RankingInfo rankingInfo, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) throws SQLException {
|
||||
insertLegStats.setString(1, trackedLegOfCompetitor.getTrackedLeg().getTrackedRace().getRace().getName());
|
||||
insertLegStats.setString(2, trackedLegOfCompetitor.getTrackedLeg().getTrackedRace().getTrackedRegatta().getRegatta().getName());
|
||||
insertLegStats.setInt(3, trackedLegOfCompetitor.getTrackedLeg().getLeg().getZeroBasedIndexOfStartWaypoint());
|
||||
insertLegStats.setString(4, trackedLegOfCompetitor.getCompetitor().getId().toString());
|
||||
insertLegStats.setInt(5, trackedLegOfCompetitor.getRank(now));
|
||||
setDouble(insertLegStats, 6, metersOr0ForNull(trackedLegOfCompetitor.getDistanceTraveled(now)));
|
||||
setDouble(insertLegStats, 7, secondsOr0ForNull(trackedLegOfCompetitor.getTime(now)));
|
||||
setDouble(insertLegStats, 8, metersOr0ForNull(trackedLegOfCompetitor.getAverageSignedCrossTrackError(now, /* waitForLatest */ false)));
|
||||
setDouble(insertLegStats, 9, metersOr0ForNull(trackedLegOfCompetitor.getAverageAbsoluteCrossTrackError(now, /* waitForLatest */ false)));
|
||||
try {
|
||||
insertLegStats.setInt(10, intOr0ForNull(trackedLegOfCompetitor.getNumberOfTacks(now, /* waitForLatest */ false)));
|
||||
insertLegStats.setInt(11, intOr0ForNull(trackedLegOfCompetitor.getNumberOfJibes(now, /* waitForLatest */ false)));
|
||||
insertLegStats.setInt(12, intOr0ForNull(trackedLegOfCompetitor.getNumberOfPenaltyCircles(now, /* waitForLatest */ false)));
|
||||
} catch (NoWindException nwe) {
|
||||
insertLegStats.setInt(10, 0);
|
||||
insertLegStats.setInt(11, 0);
|
||||
insertLegStats.setInt(12, 0);
|
||||
}
|
||||
final Speed vmg = trackedLegOfCompetitor.getAverageVelocityMadeGood(now);
|
||||
setDouble(insertLegStats, 13, vmg==null?0:vmg.getKnots());
|
||||
setDouble(insertLegStats, 14, secondsOr0ForNull(trackedLegOfCompetitor.getGapToLeader(now, WindPositionMode.LEG_MIDDLE, rankingInfo, cache)));
|
||||
}
|
||||
|
||||
private int intOr0ForNull(Integer i) {
|
||||
return i==null?0:i;
|
||||
}
|
||||
|
||||
private void parameterizeInsertLegsStatement(PreparedStatement insertLegs, TimePoint now, Regatta regatta, TrackedRace trackedRace, TrackedLeg trackedLeg) throws SQLException {
|
||||
insertLegs.setString(1, trackedRace.getRace().getName());
|
||||
insertLegs.setString(2, trackedRace.getTrackedRegatta().getRegatta().getName());
|
||||
insertLegs.setInt(3, trackedLeg.getLeg().getZeroBasedIndexOfStartWaypoint());
|
||||
final LegType legType;
|
||||
try {
|
||||
legType = trackedLeg.getLegType(now);
|
||||
insertLegs.setString(4, legType.name());
|
||||
} catch (NoWindException nwe) {
|
||||
insertLegs.setString(4, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void parameterizeInsertRaceStats(PreparedStatement insertRaceStats, TimePoint now, Waypoint startWaypoint,
|
||||
Competitor competitor, TrackedRace trackedRace) throws SQLException {
|
||||
insertRaceStats.setString(1, trackedRace.getRace().getName());
|
||||
insertRaceStats.setString(2, trackedRace.getTrackedRegatta().getRegatta().getName());
|
||||
insertRaceStats.setString(3, competitor.getId().toString());
|
||||
insertRaceStats.setInt(4, trackedRace.getRank(competitor, now));
|
||||
setDouble(insertRaceStats, 5, metersOr0ForNull(trackedRace.getDistanceTraveled(competitor, now)));
|
||||
setDouble(insertRaceStats, 6, secondsOr0ForNull(trackedRace.getTimeSailedSinceRaceStart(competitor, now)));
|
||||
setDouble(insertRaceStats, 7, metersOr0ForNull(trackedRace.getAverageSignedCrossTrackError(competitor, now, /* waitForLatest */ false)));
|
||||
setDouble(insertRaceStats, 8, metersOr0ForNull(trackedRace.getAverageAbsoluteCrossTrackError(competitor, now, /* waitForLatest */ false)));
|
||||
final Iterable<Maneuver> maneuvers = trackedRace.getManeuvers(competitor, /* waitForLatest */ false);
|
||||
insertRaceStats.setInt(9, Util.size(Util.filter(maneuvers, m->m.getType() == ManeuverType.TACK)));
|
||||
insertRaceStats.setInt(10, Util.size(Util.filter(maneuvers, m->m.getType() == ManeuverType.JIBE)));
|
||||
insertRaceStats.setInt(11, Util.size(Util.filter(maneuvers, m->m.getType() == ManeuverType.PENALTY_CIRCLE)));
|
||||
final TimePoint startOfRace = trackedRace.getStartOfRace();
|
||||
final double startDelay;
|
||||
Tack startTack;
|
||||
if (startWaypoint != null && startOfRace != null) {
|
||||
NavigableSet<MarkPassing> competitorMarkPassings = trackedRace.getMarkPassings(competitor);
|
||||
trackedRace.lockForRead(competitorMarkPassings);
|
||||
try {
|
||||
if (!Util.isEmpty(competitorMarkPassings)) {
|
||||
final MarkPassing competitorStartMarkPassing = competitorMarkPassings.iterator().next();
|
||||
final TimePoint competitorStartTime = competitorStartMarkPassing.getTimePoint();
|
||||
startDelay = secondsOr0ForNull(startOfRace.until(competitorStartTime));
|
||||
try {
|
||||
startTack = trackedRace.getTack(competitor, competitorStartTime);
|
||||
} catch (NoWindException e) {
|
||||
startTack = null;
|
||||
}
|
||||
} else {
|
||||
startDelay = 0;
|
||||
startTack = null;
|
||||
}
|
||||
} finally {
|
||||
trackedRace.unlockAfterRead(competitorMarkPassings);
|
||||
}
|
||||
} else {
|
||||
startDelay = 0;
|
||||
startTack = null;
|
||||
}
|
||||
setDouble(insertRaceStats, 12, startDelay);
|
||||
if (startOfRace != null) {
|
||||
setDouble(insertRaceStats, 13, metersOr0ForNull(trackedRace.getDistanceToStartLine(competitor, startOfRace)));
|
||||
final Speed speedWhenCrossingStartLine = trackedRace.getSpeedWhenCrossingStartLine(competitor);
|
||||
setDouble(insertRaceStats, 14, speedWhenCrossingStartLine==null?0:speedWhenCrossingStartLine.getKnots());
|
||||
insertRaceStats.setString(15, startTack==null?null:startTack.name());
|
||||
} else {
|
||||
setDouble(insertRaceStats, 13, 0);
|
||||
setDouble(insertRaceStats, 14, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private double metersOr0ForNull(final Distance distance) {
|
||||
return distance == null ? 0 : distance.getMeters();
|
||||
}
|
||||
|
||||
private double secondsOr0ForNull(final Duration duration) {
|
||||
return duration == null ? 0 : duration.asSeconds();
|
||||
}
|
||||
|
||||
private void parameterizeInsertRaceResult(PreparedStatement insertRaceResults, TimePoint now,
|
||||
Competitor competitor, Leaderboard leaderboard, RaceColumn raceColumn, Regatta regatta) throws SQLException {
|
||||
insertRaceResults.setString(1, regatta.getName());
|
||||
insertRaceResults.setString(2, raceColumn.getName());
|
||||
insertRaceResults.setString(3, competitor.getId().toString());
|
||||
final Double totalPoints = leaderboard.getTotalPoints(competitor, raceColumn, now);
|
||||
setDouble(insertRaceResults, 4, totalPoints == null ? 0 : totalPoints);
|
||||
insertRaceResults.setBoolean(5, leaderboard.isDiscarded(competitor, raceColumn, now));
|
||||
final MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitor, raceColumn, now);
|
||||
insertRaceResults.setString(6, (maxPointsReason == null ? MaxPointsReason.NONE : maxPointsReason).name());
|
||||
}
|
||||
|
||||
private void parameterizeInsertRacesStatement(final PreparedStatement insertRaces, final Regatta regatta,
|
||||
final RaceColumn raceColumn, final Fleet fleet, final TrackedRace trackedRace) throws SQLException {
|
||||
insertRaces.setString(1, trackedRace.getRace().getName());
|
||||
assert trackedRace.getTrackedRegatta().getRegatta() == regatta;
|
||||
insertRaces.setString(2, trackedRace.getTrackedRegatta().getRegatta().getName());
|
||||
insertRaces.setString(3, raceColumn.getName());
|
||||
insertRaces.setString(4, fleet.getName());
|
||||
if (trackedRace.getStartOfTracking() != null) {
|
||||
insertRaces.setDate(5, new Date(trackedRace.getStartOfTracking().asMillis()));
|
||||
} else {
|
||||
insertRaces.setDate(5, null);
|
||||
}
|
||||
if (trackedRace.getStartOfRace() != null) {
|
||||
insertRaces.setDate(6, new Date(trackedRace.getStartOfRace().asMillis()));
|
||||
} else {
|
||||
insertRaces.setDate(6, null);
|
||||
}
|
||||
if (trackedRace.getEndOfTracking() != null) {
|
||||
insertRaces.setDate(7, new Date(trackedRace.getEndOfTracking().asMillis()));
|
||||
} else {
|
||||
insertRaces.setDate(7, null);
|
||||
}
|
||||
if (trackedRace.getEndOfRace() != null) {
|
||||
insertRaces.setDate(8, new Date(trackedRace.getEndOfRace().asMillis()));
|
||||
} else {
|
||||
insertRaces.setDate(8, null);
|
||||
}
|
||||
final SpeedWithConfidence<TimePoint> averageWind = trackedRace.getAverageWindSpeedWithConfidenceWithNumberOfSamples(/* number of samples */ 5);
|
||||
if (averageWind != null) {
|
||||
setDouble(insertRaces, 9, averageWind.getObject().getKnots());
|
||||
} else {
|
||||
setDouble(insertRaces, 9, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Produces("application/json;charset=UTF-8")
|
||||
@Path("createtables")
|
||||
public Response createTables(@QueryParam("drop") boolean drop) throws SQLException, IOException {
|
||||
public Response createTables(@QueryParam("drop") boolean drop,
|
||||
@FormParam("dbendpoint") String dbEndpoint,
|
||||
@FormParam("dbuser") String dbUser,
|
||||
@FormParam("dbpassword") String dbPassword) throws SQLException, IOException {
|
||||
SecurityUtils.getSubject().checkPermission(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
SecuredSecurityTypes.ServerActions.CAN_EXPORT_MASTERDATA,
|
||||
new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
final Connection connection = HanaConnectionFactory.INSTANCE.getConnection();
|
||||
final Connection connection = HanaConnectionFactory.INSTANCE.getConnection(Optional.ofNullable(dbEndpoint),
|
||||
Optional.ofNullable(dbUser), Optional.ofNullable(dbPassword));
|
||||
if (drop) {
|
||||
logger.info("Dropping HANA Cloud SAILING DB tables on behalf of user "+SecurityUtils.getSubject().getPrincipal());
|
||||
tryExecutingQueriesFromSqlResource("/droptables.sql", connection);
|
||||
@@ -489,12 +310,4 @@ public class HanaCloudSacExportResource extends SharedAbstractSailingServerResou
|
||||
connection.createStatement().execute(statementAsString);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDouble(PreparedStatement statement, int parameterIndex, double value) throws SQLException {
|
||||
if (Double.isNaN(value) || Double.isInfinite(value)) {
|
||||
setDouble(statement, parameterIndex, 0.0);
|
||||
} else {
|
||||
statement.setDouble(parameterIndex, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
|
||||
public class InsertBoatClassStatement extends AbstractPreparedInsertStatement<BoatClass> {
|
||||
protected InsertBoatClassStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"BoatClass\" (\"id\", \"description\", \"hullLengthInMeters\", \"hullBeamInMeters\", \"hullType\") VALUES (?, ?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(BoatClass boatClass) throws SQLException {
|
||||
if (boatClass.getName() == null) {
|
||||
getPreparedStatement().setString(1, "<null>");
|
||||
} else {
|
||||
getPreparedStatement().setString(1, boatClass.getName().substring(0, Math.min(boatClass.getName().length(), 255)));
|
||||
}
|
||||
getPreparedStatement().setString(2, "Type "+boatClass.getHullType().name()+", length "+
|
||||
boatClass.getHullLength().getMeters()+"m, beam "+boatClass.getHullBeam().getMeters()+"m");
|
||||
setDouble(3, boatClass.getHullLength().getMeters());
|
||||
setDouble(4, boatClass.getHullBeam().getMeters());
|
||||
getPreparedStatement().setString(5, boatClass.getHullType().name());
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
|
||||
public class InsertCompetitorStatement extends AbstractPreparedInsertStatement<Competitor> {
|
||||
protected InsertCompetitorStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Competitor\" (\"id\", \"name\", \"shortName\", \"nationality\", \"sailNumber\") VALUES (?, ?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(Competitor competitor) throws SQLException {
|
||||
getPreparedStatement().setString(1, competitor.getId().toString());
|
||||
getPreparedStatement().setString(2, competitor.getName());
|
||||
getPreparedStatement().setString(3, competitor.getShortName());
|
||||
getPreparedStatement().setString(4, competitor.getNationality() == null ? " " : competitor.getNationality().getThreeLetterIOCAcronym());
|
||||
getPreparedStatement().setString(5, competitor.hasBoat() ? ((CompetitorWithBoat) competitor).getBoat().getSailID() : null);
|
||||
}
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Date;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
|
||||
public class InsertEventStatement extends AbstractPreparedInsertStatement<Event> {
|
||||
protected InsertEventStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Event\" (\"id\", \"name\", \"startDate\", \"endDate\", \"venue\", \"isListed\", \"description\", \"location\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, new ST_GEOMETRY('POINT('|| ? || ' ' || ? ||')', 4326).ST_Transform(3857));"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(Event event) throws SQLException {
|
||||
getPreparedStatement().setString(1, event.getId().toString());
|
||||
getPreparedStatement().setString(2, event.getName());
|
||||
getPreparedStatement().setDate(3, event.getStartDate()==null?null:new Date(event.getStartDate().asMillis()));
|
||||
getPreparedStatement().setDate(4, event.getEndDate()==null?null:new Date(event.getEndDate().asMillis()));
|
||||
getPreparedStatement().setString(5, event.getVenue().getName());
|
||||
getPreparedStatement().setBoolean(6, event.isPublic());
|
||||
getPreparedStatement().setString(7, event.getDescription());
|
||||
final Position location = event.getLocation();
|
||||
getPreparedStatement().setString(8, location != null ? String.format("%1.8f", location.getLngDeg()) : null);
|
||||
getPreparedStatement().setString(9, location != null ? String.format("%1.8f", location.getLatDeg()) : null);
|
||||
}
|
||||
}
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
|
||||
public class InsertIrmStatement extends AbstractPreparedInsertStatement<MaxPointsReason> {
|
||||
protected InsertIrmStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"IRM\" (\"name\", \"discardable\", \"advanceCompetitorsTrackedWorse\", \"appliesAtStartOfRace\") VALUES (?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(MaxPointsReason irm) throws SQLException {
|
||||
getPreparedStatement().setString(1, irm.name());
|
||||
getPreparedStatement().setBoolean(2, irm.isDiscardable());
|
||||
getPreparedStatement().setBoolean(3, irm.isAdvanceCompetitorsTrackedWorse());
|
||||
getPreparedStatement().setBoolean(4, irm.isAppliesAtStartOfRace());
|
||||
}
|
||||
}
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.hanaexport.jaxrs.api.InsertLegStatement.TrackedLegAndNow;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class InsertLegStatement extends AbstractPreparedInsertStatement<TrackedLegAndNow> {
|
||||
static class TrackedLegAndNow {
|
||||
private final TimePoint now;
|
||||
private final TrackedLeg trackedLeg;
|
||||
public TrackedLegAndNow(TimePoint now, TrackedLeg trackedLeg) {
|
||||
super();
|
||||
this.now = now;
|
||||
this.trackedLeg = trackedLeg;
|
||||
}
|
||||
public TimePoint getNow() {
|
||||
return now;
|
||||
}
|
||||
public TrackedLeg getTrackedLeg() {
|
||||
return trackedLeg;
|
||||
}
|
||||
}
|
||||
|
||||
protected InsertLegStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Leg\" (\"race\", \"regatta\", \"number\", \"type\") "+
|
||||
"VALUES (?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(TrackedLegAndNow trackedLegAndNow) throws SQLException {
|
||||
getPreparedStatement().setString(1, trackedLegAndNow.getTrackedLeg().getTrackedRace().getRace().getName());
|
||||
getPreparedStatement().setString(2, trackedLegAndNow.getTrackedLeg().getTrackedRace().getTrackedRegatta().getRegatta().getName());
|
||||
getPreparedStatement().setInt(3, trackedLegAndNow.getTrackedLeg().getLeg().getZeroBasedIndexOfStartWaypoint());
|
||||
final LegType legType;
|
||||
try {
|
||||
legType = trackedLegAndNow.getTrackedLeg().getLegType(trackedLegAndNow.getNow());
|
||||
getPreparedStatement().setString(4, legType.name());
|
||||
} catch (NoWindException nwe) {
|
||||
getPreparedStatement().setString(4, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache;
|
||||
import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||
import com.sap.sailing.hanaexport.jaxrs.api.InsertLegStatsStatement.TrackedLegOfCompetitorRankingInfoCacheAndNow;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class InsertLegStatsStatement extends AbstractPreparedInsertStatement<TrackedLegOfCompetitorRankingInfoCacheAndNow> {
|
||||
static class TrackedLegOfCompetitorRankingInfoCacheAndNow {
|
||||
private final TimePoint now;
|
||||
private final RankingInfo rankingInfo;
|
||||
private final WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache;
|
||||
private final TrackedLegOfCompetitor trackedLegOfCompetitor;
|
||||
public TrackedLegOfCompetitorRankingInfoCacheAndNow(TimePoint now, RankingInfo rankingInfo,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache,
|
||||
TrackedLegOfCompetitor trackedLegOfCompetitor) {
|
||||
super();
|
||||
this.now = now;
|
||||
this.rankingInfo = rankingInfo;
|
||||
this.cache = cache;
|
||||
this.trackedLegOfCompetitor = trackedLegOfCompetitor;
|
||||
}
|
||||
public TimePoint getNow() {
|
||||
return now;
|
||||
}
|
||||
public RankingInfo getRankingInfo() {
|
||||
return rankingInfo;
|
||||
}
|
||||
public WindLegTypeAndLegBearingAndORCPerformanceCurveCache getCache() {
|
||||
return cache;
|
||||
}
|
||||
public TrackedLegOfCompetitor getTrackedLegOfCompetitor() {
|
||||
return trackedLegOfCompetitor;
|
||||
}
|
||||
}
|
||||
|
||||
protected InsertLegStatsStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"LegStats\" (\"race\", \"regatta\", \"number\", \"competitorId\", \"rankOneBased\", \"distanceSailedInMeters\", \"elapsedTimeInSeconds\", "+
|
||||
"\"avgCrossTrackErrorInMeters\", \"absoluteAvgCrossTrackErrorInMeters\", \"numberOfTacks\", "+
|
||||
"\"numberOfGybes\", \"numberOfPenaltyCircles\", \"avgVelocityMadeGoodInKnots\", \"gapToLeaderInSeconds\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(TrackedLegOfCompetitorRankingInfoCacheAndNow trackedLegOfCompetitorAndNow) throws SQLException {
|
||||
getPreparedStatement().setString(1, trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getTrackedLeg().getTrackedRace().getRace().getName());
|
||||
getPreparedStatement().setString(2, trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getTrackedLeg().getTrackedRace().getTrackedRegatta().getRegatta().getName());
|
||||
getPreparedStatement().setInt(3, trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getTrackedLeg().getLeg().getZeroBasedIndexOfStartWaypoint());
|
||||
getPreparedStatement().setString(4, trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getCompetitor().getId().toString());
|
||||
getPreparedStatement().setInt(5, trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getRank(trackedLegOfCompetitorAndNow.getNow()));
|
||||
setDouble(6, metersOr0ForNull(trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getDistanceTraveled(trackedLegOfCompetitorAndNow.getNow())));
|
||||
setDouble(7, secondsOr0ForNull(trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getTime(trackedLegOfCompetitorAndNow.getNow())));
|
||||
setDouble(8, metersOr0ForNull(trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getAverageSignedCrossTrackError(trackedLegOfCompetitorAndNow.getNow(), /* waitForLatest */ false)));
|
||||
setDouble(9, metersOr0ForNull(trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getAverageAbsoluteCrossTrackError(trackedLegOfCompetitorAndNow.getNow(), /* waitForLatest */ false)));
|
||||
try {
|
||||
getPreparedStatement().setInt(10, intOr0ForNull(trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getNumberOfTacks(trackedLegOfCompetitorAndNow.getNow(), /* waitForLatest */ false)));
|
||||
getPreparedStatement().setInt(11, intOr0ForNull(trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getNumberOfJibes(trackedLegOfCompetitorAndNow.getNow(), /* waitForLatest */ false)));
|
||||
getPreparedStatement().setInt(12, intOr0ForNull(trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getNumberOfPenaltyCircles(trackedLegOfCompetitorAndNow.getNow(), /* waitForLatest */ false)));
|
||||
} catch (NoWindException nwe) {
|
||||
getPreparedStatement().setInt(10, 0);
|
||||
getPreparedStatement().setInt(11, 0);
|
||||
getPreparedStatement().setInt(12, 0);
|
||||
}
|
||||
final Speed vmg = trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getAverageVelocityMadeGood(trackedLegOfCompetitorAndNow.getNow());
|
||||
setDouble(13, vmg==null?0:vmg.getKnots());
|
||||
setDouble(14, secondsOr0ForNull(trackedLegOfCompetitorAndNow.getTrackedLegOfCompetitor().getGapToLeader(trackedLegOfCompetitorAndNow.getNow(), WindPositionMode.LEG_MIDDLE,
|
||||
trackedLegOfCompetitorAndNow.getRankingInfo(), trackedLegOfCompetitorAndNow.getCache())));
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Date;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.hanaexport.jaxrs.api.InsertManeuverStatement.ManeuverTrackedRaceAndCompetitor;
|
||||
|
||||
public class InsertManeuverStatement extends AbstractPreparedInsertStatement<ManeuverTrackedRaceAndCompetitor> {
|
||||
static class ManeuverTrackedRaceAndCompetitor {
|
||||
private final Maneuver maneuver;
|
||||
private final TrackedRace trackedRace;
|
||||
private final Competitor competitor;
|
||||
public ManeuverTrackedRaceAndCompetitor(Maneuver maneuver, TrackedRace trackedRace, Competitor competitor) {
|
||||
super();
|
||||
this.maneuver = maneuver;
|
||||
this.trackedRace = trackedRace;
|
||||
this.competitor = competitor;
|
||||
}
|
||||
public Maneuver getManeuver() {
|
||||
return maneuver;
|
||||
}
|
||||
public TrackedRace getTrackedRace() {
|
||||
return trackedRace;
|
||||
}
|
||||
public Competitor getCompetitor() {
|
||||
return competitor;
|
||||
}
|
||||
}
|
||||
|
||||
protected InsertManeuverStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Maneuver\" (\"race\", \"regatta\", \"competitorId\", \"timepoint\", \"type\", \"newTack\", "+
|
||||
"\"lossInMeters\", \"speedBeforeInKnots\", \"speedAfterInKnots\", "+
|
||||
"\"courseBeforeInTrueDegrees\", \"courseAfterInTrueDegrees\", \"directionChangeInDegrees\", \"maximumTurningRateInDegreesPerSecond\", "+
|
||||
"\"lowestSpeedInKnots\", \"toSide\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(ManeuverTrackedRaceAndCompetitor maneuverTrackedRaceAndCompetitor) throws SQLException {
|
||||
getPreparedStatement().setString(1, maneuverTrackedRaceAndCompetitor.getTrackedRace().getRace().getName());
|
||||
getPreparedStatement().setString(2, maneuverTrackedRaceAndCompetitor.getTrackedRace().getTrackedRegatta().getRegatta().getName());
|
||||
getPreparedStatement().setString(3, maneuverTrackedRaceAndCompetitor.getCompetitor().getId().toString());
|
||||
getPreparedStatement().setDate(4, new Date(maneuverTrackedRaceAndCompetitor.getManeuver().getTimePoint().asMillis()));
|
||||
getPreparedStatement().setString(5, maneuverTrackedRaceAndCompetitor.getManeuver().getType().name());
|
||||
getPreparedStatement().setString(6, maneuverTrackedRaceAndCompetitor.getManeuver().getNewTack().name());
|
||||
if (maneuverTrackedRaceAndCompetitor.getManeuver().getManeuverLoss() != null) {
|
||||
setDouble(7,
|
||||
maneuverTrackedRaceAndCompetitor.getManeuver().getManeuverLoss().getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters()
|
||||
-maneuverTrackedRaceAndCompetitor.getManeuver().getManeuverLoss().getDistanceSailedProjectedOnMiddleManeuverAngle().getMeters());
|
||||
} else {
|
||||
setDouble(7, 0);
|
||||
}
|
||||
setDouble(8, maneuverTrackedRaceAndCompetitor.getManeuver().getSpeedWithBearingBefore().getKnots());
|
||||
setDouble(9, maneuverTrackedRaceAndCompetitor.getManeuver().getSpeedWithBearingAfter().getKnots());
|
||||
setDouble(10, maneuverTrackedRaceAndCompetitor.getManeuver().getSpeedWithBearingBefore().getBearing().getDegrees());
|
||||
setDouble(11, maneuverTrackedRaceAndCompetitor.getManeuver().getSpeedWithBearingAfter().getBearing().getDegrees());
|
||||
setDouble(12, maneuverTrackedRaceAndCompetitor.getManeuver().getDirectionChangeInDegrees());
|
||||
setDouble(13, maneuverTrackedRaceAndCompetitor.getManeuver().getMaxTurningRateInDegreesPerSecond());
|
||||
setDouble(14, maneuverTrackedRaceAndCompetitor.getManeuver().getLowestSpeed().getKnots());
|
||||
getPreparedStatement().setString(15, maneuverTrackedRaceAndCompetitor.getManeuver().getToSide().name());
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.hanaexport.jaxrs.api.InsertRaceResultStatement.RaceResult;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class InsertRaceResultStatement extends AbstractPreparedInsertStatement<RaceResult> {
|
||||
static class RaceResult {
|
||||
private final Regatta regatta;
|
||||
private final Leaderboard leaderboard;
|
||||
private final Competitor competitor;
|
||||
private final RaceColumn raceColumn;
|
||||
private final TimePoint now;
|
||||
public RaceResult(Regatta regatta, Leaderboard leaderboard, Competitor competitor, RaceColumn raceColumn,
|
||||
TimePoint now) {
|
||||
super();
|
||||
this.regatta = regatta;
|
||||
this.leaderboard = leaderboard;
|
||||
this.competitor = competitor;
|
||||
this.raceColumn = raceColumn;
|
||||
this.now = now;
|
||||
}
|
||||
public Regatta getRegatta() {
|
||||
return regatta;
|
||||
}
|
||||
public Leaderboard getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
public Competitor getCompetitor() {
|
||||
return competitor;
|
||||
}
|
||||
public RaceColumn getRaceColumn() {
|
||||
return raceColumn;
|
||||
}
|
||||
public TimePoint getNow() {
|
||||
return now;
|
||||
}
|
||||
}
|
||||
|
||||
protected InsertRaceResultStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"RaceResult\" (\"regatta\", \"raceColumn\", \"competitorId\", \"points\", "+
|
||||
"\"discarded\", \"irm\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(RaceResult raceResult) throws SQLException {
|
||||
getPreparedStatement().setString(1, raceResult.getRegatta().getName());
|
||||
getPreparedStatement().setString(2, raceResult.getRaceColumn().getName());
|
||||
getPreparedStatement().setString(3, raceResult.getCompetitor().getId().toString());
|
||||
final Double totalPoints = raceResult.getLeaderboard().getTotalPoints(raceResult.getCompetitor(), raceResult.getRaceColumn(), raceResult.getNow());
|
||||
setDouble(4, totalPoints == null ? 0 : totalPoints);
|
||||
getPreparedStatement().setBoolean(5, raceResult.getLeaderboard().isDiscarded(raceResult.getCompetitor(), raceResult.getRaceColumn(), raceResult.getNow()));
|
||||
final MaxPointsReason maxPointsReason = raceResult.getLeaderboard().getMaxPointsReason(raceResult.getCompetitor(), raceResult.getRaceColumn(), raceResult.getNow());
|
||||
getPreparedStatement().setString(6, (maxPointsReason == null ? MaxPointsReason.NONE : maxPointsReason).name());
|
||||
}
|
||||
}
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Date;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.SpeedWithConfidence;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.hanaexport.jaxrs.api.InsertRaceStatement.TrackedRaceWithRaceColumnAndFleet;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class InsertRaceStatement extends AbstractPreparedInsertStatement<TrackedRaceWithRaceColumnAndFleet> {
|
||||
static class TrackedRaceWithRaceColumnAndFleet {
|
||||
private final TrackedRace trackedRace;
|
||||
private final RaceColumn raceColumn;
|
||||
private final Fleet fleet;
|
||||
public TrackedRaceWithRaceColumnAndFleet(TrackedRace trackedRace, RaceColumn raceColumn, Fleet fleet) {
|
||||
super();
|
||||
this.trackedRace = trackedRace;
|
||||
this.raceColumn = raceColumn;
|
||||
this.fleet = fleet;
|
||||
}
|
||||
public TrackedRace getTrackedRace() {
|
||||
return trackedRace;
|
||||
}
|
||||
public RaceColumn getRaceColumn() {
|
||||
return raceColumn;
|
||||
}
|
||||
public Fleet getFleet() {
|
||||
return fleet;
|
||||
}
|
||||
}
|
||||
|
||||
protected InsertRaceStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Race\" (\"name\", \"regatta\", \"raceColumn\", \"fleet\", \"startOfTracking\", "+
|
||||
"\"startOfRace\", \"endOfTracking\", \"endOfRace\", \"avgWindSpeedInKnots\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(TrackedRaceWithRaceColumnAndFleet raceColumnFleetAndTrackedRace) throws SQLException {
|
||||
final TrackedRace trackedRace = raceColumnFleetAndTrackedRace.getTrackedRace();
|
||||
getPreparedStatement().setString(1, trackedRace.getRace().getName());
|
||||
getPreparedStatement().setString(2, trackedRace.getTrackedRegatta().getRegatta().getName());
|
||||
getPreparedStatement().setString(3, raceColumnFleetAndTrackedRace.getRaceColumn().getName());
|
||||
getPreparedStatement().setString(4, raceColumnFleetAndTrackedRace.getFleet().getName());
|
||||
if (trackedRace.getStartOfTracking() != null) {
|
||||
getPreparedStatement().setDate(5, new Date(trackedRace.getStartOfTracking().asMillis()));
|
||||
} else {
|
||||
getPreparedStatement().setDate(5, null);
|
||||
}
|
||||
if (trackedRace.getStartOfRace() != null) {
|
||||
getPreparedStatement().setDate(6, new Date(trackedRace.getStartOfRace().asMillis()));
|
||||
} else {
|
||||
getPreparedStatement().setDate(6, null);
|
||||
}
|
||||
if (trackedRace.getEndOfTracking() != null) {
|
||||
getPreparedStatement().setDate(7, new Date(trackedRace.getEndOfTracking().asMillis()));
|
||||
} else {
|
||||
getPreparedStatement().setDate(7, null);
|
||||
}
|
||||
if (trackedRace.getEndOfRace() != null) {
|
||||
getPreparedStatement().setDate(8, new Date(trackedRace.getEndOfRace().asMillis()));
|
||||
} else {
|
||||
getPreparedStatement().setDate(8, null);
|
||||
}
|
||||
final SpeedWithConfidence<TimePoint> averageWind = trackedRace.getAverageWindSpeedWithConfidenceWithNumberOfSamples(/* number of samples */ 5);
|
||||
if (averageWind != null) {
|
||||
setDouble(9, averageWind.getObject().getKnots());
|
||||
} else {
|
||||
setDouble(9, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.NavigableSet;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.hanaexport.jaxrs.api.InsertRaceStatsStatement.TrackedRaceWithCompetitorAndStartWaypoint;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class InsertRaceStatsStatement extends AbstractPreparedInsertStatement<TrackedRaceWithCompetitorAndStartWaypoint> {
|
||||
static class TrackedRaceWithCompetitorAndStartWaypoint {
|
||||
private final TimePoint now;
|
||||
private final Waypoint startWaypoint;
|
||||
private final Competitor competitor;
|
||||
private final TrackedRace trackedRace;
|
||||
public TrackedRaceWithCompetitorAndStartWaypoint(TimePoint now, Waypoint startWaypoint, Competitor competitor,
|
||||
TrackedRace trackedRace) {
|
||||
super();
|
||||
this.now = now;
|
||||
this.startWaypoint = startWaypoint;
|
||||
this.competitor = competitor;
|
||||
this.trackedRace = trackedRace;
|
||||
}
|
||||
public TimePoint getNow() {
|
||||
return now;
|
||||
}
|
||||
public Waypoint getStartWaypoint() {
|
||||
return startWaypoint;
|
||||
}
|
||||
public Competitor getCompetitor() {
|
||||
return competitor;
|
||||
}
|
||||
public TrackedRace getTrackedRace() {
|
||||
return trackedRace;
|
||||
}
|
||||
}
|
||||
|
||||
protected InsertRaceStatsStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"RaceStats\" (\"race\", \"regatta\", \"competitorId\", \"rankOneBased\", \"distanceSailedInMeters\", \"elapsedTimeInSeconds\", "+
|
||||
"\"avgCrossTrackErrorInMeters\", \"absoluteAvgCrossTrackErrorInMeters\", \"numberOfTacks\", "+
|
||||
"\"numberOfGybes\", \"numberOfPenaltyCircles\", \"startDelayInSeconds\", \"distanceFromStartLineInMetersAtStart\", "+
|
||||
"\"speedWhenCrossingStartLineInKnots\", \"startTack\") "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(TrackedRaceWithCompetitorAndStartWaypoint raceColumnFleetAndTrackedRace) throws SQLException {
|
||||
final TrackedRace trackedRace = raceColumnFleetAndTrackedRace.getTrackedRace();
|
||||
final Competitor competitor = raceColumnFleetAndTrackedRace.getCompetitor();
|
||||
final TimePoint now = raceColumnFleetAndTrackedRace.getNow();
|
||||
getPreparedStatement().setString(1, trackedRace.getRace().getName());
|
||||
getPreparedStatement().setString(2, trackedRace.getTrackedRegatta().getRegatta().getName());
|
||||
getPreparedStatement().setString(3, competitor.getId().toString());
|
||||
getPreparedStatement().setInt(4, trackedRace.getRank(competitor, now));
|
||||
setDouble(5, metersOr0ForNull(trackedRace.getDistanceTraveled(competitor, now)));
|
||||
setDouble(6, secondsOr0ForNull(trackedRace.getTimeSailedSinceRaceStart(competitor, now)));
|
||||
setDouble(7, metersOr0ForNull(trackedRace.getAverageSignedCrossTrackError(competitor, now, /* waitForLatest */ false)));
|
||||
setDouble(8, metersOr0ForNull(trackedRace.getAverageAbsoluteCrossTrackError(competitor, now, /* waitForLatest */ false)));
|
||||
final Iterable<Maneuver> maneuvers = trackedRace.getManeuvers(competitor, /* waitForLatest */ false);
|
||||
getPreparedStatement().setInt(9, Util.size(Util.filter(maneuvers, m->m.getType() == ManeuverType.TACK)));
|
||||
getPreparedStatement().setInt(10, Util.size(Util.filter(maneuvers, m->m.getType() == ManeuverType.JIBE)));
|
||||
getPreparedStatement().setInt(11, Util.size(Util.filter(maneuvers, m->m.getType() == ManeuverType.PENALTY_CIRCLE)));
|
||||
final TimePoint startOfRace = trackedRace.getStartOfRace();
|
||||
final double startDelay;
|
||||
Tack startTack;
|
||||
if (raceColumnFleetAndTrackedRace.getStartWaypoint() != null && startOfRace != null) {
|
||||
NavigableSet<MarkPassing> competitorMarkPassings = trackedRace.getMarkPassings(competitor);
|
||||
trackedRace.lockForRead(competitorMarkPassings);
|
||||
try {
|
||||
if (!Util.isEmpty(competitorMarkPassings)) {
|
||||
final MarkPassing competitorStartMarkPassing = competitorMarkPassings.iterator().next();
|
||||
final TimePoint competitorStartTime = competitorStartMarkPassing.getTimePoint();
|
||||
startDelay = secondsOr0ForNull(startOfRace.until(competitorStartTime));
|
||||
try {
|
||||
startTack = trackedRace.getTack(competitor, competitorStartTime);
|
||||
} catch (NoWindException e) {
|
||||
startTack = null;
|
||||
}
|
||||
} else {
|
||||
startDelay = 0;
|
||||
startTack = null;
|
||||
}
|
||||
} finally {
|
||||
trackedRace.unlockAfterRead(competitorMarkPassings);
|
||||
}
|
||||
} else {
|
||||
startDelay = 0;
|
||||
startTack = null;
|
||||
}
|
||||
setDouble(12, startDelay);
|
||||
if (startOfRace != null) {
|
||||
setDouble(13, metersOr0ForNull(trackedRace.getDistanceToStartLine(competitor, startOfRace)));
|
||||
final Speed speedWhenCrossingStartLine = trackedRace.getSpeedWhenCrossingStartLine(competitor);
|
||||
setDouble(14, speedWhenCrossingStartLine==null?0:speedWhenCrossingStartLine.getKnots());
|
||||
getPreparedStatement().setString(15, startTack==null?null:startTack.name());
|
||||
} else {
|
||||
setDouble(13, 0);
|
||||
setDouble(14, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
java/com.sap.sailing.hanaexport/src/com/sap/sailing/hanaexport/jaxrs/api/InsertRegattaStatement.java
Executable
+43
@@ -0,0 +1,43 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.hanaexport.jaxrs.api.InsertRegattaStatement.RegattaAndEvent;
|
||||
|
||||
public class InsertRegattaStatement extends AbstractPreparedInsertStatement<RegattaAndEvent> {
|
||||
static class RegattaAndEvent {
|
||||
private final Regatta regatta;
|
||||
private final Event event;
|
||||
public RegattaAndEvent(Regatta regatta, Event event) {
|
||||
super();
|
||||
this.regatta = regatta;
|
||||
this.event = event;
|
||||
}
|
||||
public Regatta getRegatta() {
|
||||
return regatta;
|
||||
}
|
||||
public Event getEvent() {
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
protected InsertRegattaStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"Regatta\" (\"name\", \"boatClass\", \"scoringScheme\", \"rankingMetric\", \"eventId\") "+
|
||||
"VALUES (?, ?, ?, ?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(RegattaAndEvent regattaAndEvent) throws SQLException {
|
||||
final Regatta regatta = regattaAndEvent.getRegatta();
|
||||
final Event event = regattaAndEvent.getEvent();
|
||||
getPreparedStatement().setString(1, regatta.getName());
|
||||
getPreparedStatement().setString(2, regatta.getBoatClass().getName());
|
||||
getPreparedStatement().setString(3, regatta.getScoringScheme().getType().name());
|
||||
getPreparedStatement().setString(4, regatta.getRankingMetricType().name());
|
||||
getPreparedStatement().setString(5, event == null ? null : event.getId().toString());
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
|
||||
public class InsertScoringSchemeStatement extends AbstractPreparedInsertStatement<ScoringScheme> {
|
||||
protected InsertScoringSchemeStatement(Connection connection) throws SQLException {
|
||||
super(connection.prepareStatement(
|
||||
"INSERT INTO SAILING.\"ScoringScheme\" (\"id\", \"higherIsBetter\") VALUES (?, ?);"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parameterizeStatement(ScoringScheme scoringScheme) throws SQLException {
|
||||
getPreparedStatement().setString(1, scoringScheme.getType().name());
|
||||
getPreparedStatement().setBoolean(2, scoringScheme.isHigherBetter());
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.sap.sailing.hanaexport.jaxrs.api;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Can insert objects of type {@code T} using a prepared statement, in batch mode.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public interface PreparedInsertStatement<T> {
|
||||
PreparedStatement getPreparedStatement();
|
||||
|
||||
void parameterizeStatement(T objectToInsert) throws SQLException;
|
||||
|
||||
default void insert(T objectToInsert) throws SQLException {
|
||||
parameterizeStatement(objectToInsert);
|
||||
getPreparedStatement().execute();
|
||||
}
|
||||
|
||||
default void insertBatch(Iterable<T> objectsToInsert) throws SQLException {
|
||||
for (final T objectToInsert : objectsToInsert) {
|
||||
insertBatch(objectToInsert);
|
||||
}
|
||||
}
|
||||
|
||||
default void insertBatch(final T objectToInsert) throws SQLException {
|
||||
parameterizeStatement(objectToInsert);
|
||||
getPreparedStatement().addBatch();
|
||||
}
|
||||
|
||||
default int[] executeBatch() throws SQLException {
|
||||
return getPreparedStatement().executeBatch();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -141,7 +141,7 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
|
||||
/**
|
||||
* The timeout for a host to come up
|
||||
*/
|
||||
private static final Optional<Duration> WAIT_FOR_HOST_TIMEOUT = Optional.of(Duration.ONE_MINUTE.times(10));
|
||||
private static final Optional<Duration> WAIT_FOR_HOST_TIMEOUT = Optional.of(Duration.ONE_MINUTE.times(30));
|
||||
|
||||
private static final String SAILING_TARGET_GROUP_NAME_PREFIX = "S-";
|
||||
|
||||
|
||||
+12
@@ -8,6 +8,8 @@ import com.sap.sse.landscape.DefaultProcessConfigurationVariables;
|
||||
import com.sap.sse.landscape.InboundReplicationConfiguration;
|
||||
import com.sap.sse.landscape.OutboundReplicationConfiguration;
|
||||
import com.sap.sse.landscape.ProcessConfigurationVariable;
|
||||
import com.sap.sse.landscape.mongodb.Database;
|
||||
import com.sap.sse.landscape.mongodb.MongoEndpoint;
|
||||
|
||||
public class SailingAnalyticsReplicaConfiguration<ShardingKey>
|
||||
extends SailingAnalyticsApplicationConfiguration<ShardingKey> {
|
||||
@@ -24,6 +26,8 @@ extends SailingAnalyticsApplicationConfiguration<ShardingKey> {
|
||||
* {@code "live-replica-server"}.</li>
|
||||
* <li>If no {@link #setDatabaseName(String) database name is set} explicitly, it defaults to the
|
||||
* {@link #getServerName() server name} with the suffix {@code -replica} appended to it.</li>
|
||||
* <li>If no {@link #setDatabaseConfiguration(Database) database configuration is set} explicitly, it defaults
|
||||
* to the "replica" replica set on "localhost:27017" on the replica node.</li>
|
||||
* </ul>
|
||||
*
|
||||
* TODO we could default the set of replicables to replicate, competing with the live-replica-server environment
|
||||
@@ -40,6 +44,8 @@ extends SailingAnalyticsApplicationConfiguration<ShardingKey> {
|
||||
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, ShardingKey>, ShardingKey>
|
||||
extends SailingAnalyticsApplicationConfiguration.BuilderImpl<BuilderT, SailingAnalyticsReplicaConfiguration<ShardingKey>, ShardingKey>
|
||||
implements Builder<BuilderT, ShardingKey> {
|
||||
private static final String DEFAULT_MONGO_REPLICA_SET_NAME_FOR_REPLICA = "replica";
|
||||
|
||||
@Override
|
||||
public OutboundReplicationConfiguration getOutboundReplicationConfiguration() {
|
||||
final OutboundReplicationConfiguration.Builder resultBuilder;
|
||||
@@ -56,6 +62,12 @@ extends SailingAnalyticsApplicationConfiguration<ShardingKey> {
|
||||
}
|
||||
return resultBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Database getDatabaseConfiguration() {
|
||||
return isDatabaseConfigurationSet() ? super.getDatabaseConfiguration() :
|
||||
Database.of(MongoEndpoint.of("localhost", 27017, DEFAULT_MONGO_REPLICA_SET_NAME_FOR_REPLICA), getDatabaseName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<InboundReplicationConfiguration> getInboundReplicationConfiguration() {
|
||||
|
||||
+2
-1
@@ -43,6 +43,7 @@ import org.mockito.Matchers;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
||||
@@ -264,7 +265,7 @@ public class MasterDataImportTest {
|
||||
.spy(new RacingEventServiceImpl(null, MongoSensorFixStoreFactory.INSTANCE.getMongoGPSFixStore(
|
||||
PersistenceFactory.INSTANCE
|
||||
.getDefaultMongoObjectFactory(serviceFinderFactory), PersistenceFactory.INSTANCE
|
||||
.getDefaultDomainObjectFactory(), serviceFinderFactory, WriteConcern.MAJORITY), serviceFinderFactory));
|
||||
.getDefaultDomainObjectFactory(), serviceFinderFactory, ReadConcern.MAJORITY, WriteConcern.MAJORITY), serviceFinderFactory));
|
||||
Mockito.doReturn(securityService).when(sourceService).getSecurityService();
|
||||
Event event = sourceService.addEvent(TEST_EVENT_NAME, /* eventDescription */null, eventStartDate, eventEndDate,
|
||||
"testVenue", false, eventUUID);
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.impl.DataImportProgressImpl;
|
||||
@@ -36,7 +37,7 @@ public abstract class RacingEventServiceImplMock extends RacingEventServiceImpl
|
||||
super(null, MongoSensorFixStoreFactory.INSTANCE.getMongoGPSFixStore(
|
||||
PersistenceFactory.INSTANCE
|
||||
.getDefaultMongoObjectFactory(serviceFinderFactory), PersistenceFactory.INSTANCE
|
||||
.getDefaultDomainObjectFactory(), serviceFinderFactory, WriteConcern.MAJORITY), serviceFinderFactory);
|
||||
.getDefaultDomainObjectFactory(), serviceFinderFactory, ReadConcern.MAJORITY, WriteConcern.MAJORITY), serviceFinderFactory);
|
||||
lock = new DataImportLockWithProgress();
|
||||
lock.addProgress(dataImportProgressImpl.getOperationId(), dataImportProgressImpl);
|
||||
}
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
Contact: https://www.sap.com/report-a-vulnerability
|
||||
Encryption: https://www.sap.com/pgp-keyblock
|
||||
Policy: https://wiki.scn.sap.com/wiki/x/1s-iGg
|
||||
Acknowledgments: https://wiki.scn.sap.com/wiki/x/rc-iGg
|
||||
Expires: Mon, 31 Jan 2022 12:00 +0100
|
||||
@@ -3,6 +3,7 @@ source.. = src/,\
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
./.well-known/,\
|
||||
WEB-INF/web.xml,\
|
||||
index.html,\
|
||||
release_notes.css,\
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
<div class="mainContent">
|
||||
<h2 class="releaseHeadline">Release Notes - Administration Console</h2>
|
||||
<div class="innerContent">
|
||||
<h2 class="articleSubheadline">August 2021</h2>
|
||||
<ul class="bulletList">
|
||||
<li>Added boat classes iQFOil Men/Women/Youth</li>
|
||||
</ul>
|
||||
<h2 class="articleSubheadline">July 2021</h2>
|
||||
<ul class="bulletList">
|
||||
<li>Creating and editing a Regatta object now uses the already loaded Events with their course areas
|
||||
|
||||
@@ -789,16 +789,20 @@ public class Util {
|
||||
}
|
||||
|
||||
public static <T extends Named> List<T> sortNamedCollection(Collection<T> collection) {
|
||||
return sortNamedCollection(collection, /* caseSensitive */ true);
|
||||
}
|
||||
|
||||
public static <T extends Named> List<T> sortNamedCollection(Collection<T> collection, boolean caseSensitive) {
|
||||
List<T> sortedCollection = new ArrayList<>(collection);
|
||||
Collections.sort(sortedCollection, naturalNamedComparator());
|
||||
Collections.sort(sortedCollection, naturalNamedComparator(caseSensitive));
|
||||
return sortedCollection;
|
||||
}
|
||||
|
||||
public static <T extends Named> Comparator<T> naturalNamedComparator() {
|
||||
|
||||
public static <T extends Named> Comparator<T> naturalNamedComparator(boolean caseSensitive) {
|
||||
return new Comparator<T>() {
|
||||
@Override
|
||||
public int compare(T o1, T o2) {
|
||||
return new NaturalComparator().compare(o1.getName(), o2.getName());
|
||||
return new NaturalComparator(caseSensitive).compare(o1.getName(), o2.getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+5
-1
@@ -190,7 +190,11 @@ implements UserDataProvider {
|
||||
}
|
||||
|
||||
protected Database getDatabaseConfiguration() {
|
||||
return databaseConfiguration == null ? getLandscape().getDatabase(getRegion(), getDatabaseName()) : databaseConfiguration;
|
||||
return isDatabaseConfigurationSet() ? databaseConfiguration : getLandscape().getDatabase(getRegion(), getDatabaseName());
|
||||
}
|
||||
|
||||
protected boolean isDatabaseConfigurationSet() {
|
||||
return databaseConfiguration != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,14 +5,18 @@ import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.landscape.DefaultProcessConfigurationVariables;
|
||||
import com.sap.sse.landscape.ProcessConfigurationVariable;
|
||||
import com.sap.sse.landscape.UserDataProvider;
|
||||
import com.sap.sse.landscape.mongodb.impl.DatabaseImpl;
|
||||
|
||||
public interface Database extends UserDataProvider, Named {
|
||||
static final Logger logger = Logger.getLogger(Database.class.getName());
|
||||
|
||||
/**
|
||||
* Obtains the database-specific connection URI that clients can use to connect to the replica set hosting this
|
||||
* database. See also {@link MongoReplicaSet#getConnectionURI()}.
|
||||
@@ -48,5 +52,12 @@ public interface Database extends UserDataProvider, Named {
|
||||
/**
|
||||
* Drops the database.
|
||||
*/
|
||||
void drop() throws URISyntaxException;
|
||||
default void drop() throws URISyntaxException {
|
||||
logger.info("Dropping database "+this);
|
||||
getMongoDatabase().drop();
|
||||
}
|
||||
|
||||
static Database of(MongoEndpoint mongoEndpoint, String databaseName) {
|
||||
return new DatabaseImpl(mongoEndpoint, databaseName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.mongodb.MongoClientURI;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.session.ClientSession;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.landscape.mongodb.impl.SimpleMongoEndpointImpl;
|
||||
|
||||
/**
|
||||
* A MongoDB endpoint that an application can connect to. It can produce a {@link URI} the client can use to connect to,
|
||||
@@ -19,6 +20,14 @@ import com.sap.sse.common.Duration;
|
||||
*
|
||||
*/
|
||||
public interface MongoEndpoint {
|
||||
static MongoEndpoint of(String hostname, int port) {
|
||||
return new SimpleMongoEndpointImpl(hostname, port);
|
||||
}
|
||||
|
||||
static MongoEndpoint of(String hostname, int port, String replicaSetName) {
|
||||
return new SimpleMongoEndpointImpl(hostname, port, replicaSetName);
|
||||
}
|
||||
|
||||
/**
|
||||
* When invoked on a {@link MongoProcess} that is not currently equipped with a public IP address, a
|
||||
* {@link NullPointerException} will result. Consider using {@link #getURI(Optional, Optional)} to wait for
|
||||
@@ -28,6 +37,24 @@ public interface MongoEndpoint {
|
||||
|
||||
URI getURI(Optional<Database> optionalDb, Optional<Duration> timeoutEmptyMeaningForever) throws URISyntaxException;
|
||||
|
||||
default URI getURI(Optional<Database> optionalDb, String hostname, int port, Optional<String> replicaSetName) throws URISyntaxException {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("mongodb://");
|
||||
sb.append(hostname);
|
||||
sb.append(":");
|
||||
sb.append(port);
|
||||
sb.append("/");
|
||||
optionalDb.ifPresent(db->sb.append(db.getName()));
|
||||
replicaSetName.ifPresent(rsName->appendReplicaSetParametersToURI(rsName, sb));
|
||||
return new URI(sb.toString());
|
||||
}
|
||||
|
||||
default void appendReplicaSetParametersToURI(String replicaSetName, StringBuilder uriStringBuilder) {
|
||||
uriStringBuilder.append("?replicaSet=");
|
||||
uriStringBuilder.append(replicaSetName);
|
||||
uriStringBuilder.append("&retryWrites=true&readPreference=nearest");
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all MongoDB databases available in this end point
|
||||
*/
|
||||
|
||||
@@ -11,25 +11,14 @@ import com.sap.sse.landscape.RotatingFileBasedLog;
|
||||
public interface MongoProcess extends Process<RotatingFileBasedLog, MongoMetrics>, MongoEndpoint {
|
||||
@Override
|
||||
default URI getURI(Optional<Database> optionalDb) throws URISyntaxException {
|
||||
return getURI(optionalDb, getHostname());
|
||||
return getURI(optionalDb, getHostname(), getPort(), /* no replica set name */ Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
default URI getURI(Optional<Database> optionalDb, Optional<Duration> timeoutEmptyMeaningForever) throws URISyntaxException {
|
||||
return getURI(optionalDb, getHostname(timeoutEmptyMeaningForever));
|
||||
return getURI(optionalDb, getHostname(timeoutEmptyMeaningForever), getPort(), /* no replica set name */ Optional.empty());
|
||||
}
|
||||
|
||||
default URI getURI(Optional<Database> optionalDb, String hostname) throws URISyntaxException {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("mongodb://");
|
||||
sb.append(hostname);
|
||||
sb.append(":");
|
||||
sb.append(getPort());
|
||||
sb.append("/");
|
||||
optionalDb.ifPresent(db->sb.append(db.getName()));
|
||||
return new URI(sb.toString());
|
||||
}
|
||||
|
||||
boolean isInReplicaSet() throws URISyntaxException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,9 +49,7 @@ public interface MongoReplicaSet extends Named, MongoEndpoint {
|
||||
result.append(String.join(",", hostSpecs));
|
||||
result.append("/");
|
||||
optionalDb.ifPresent(db->result.append(db.getName()));
|
||||
result.append("?replicaSet=");
|
||||
result.append(getName());
|
||||
result.append("&retryWrites=true&readPreference=nearest");
|
||||
appendReplicaSetParametersToURI(getName(), result);
|
||||
return new URI(result.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package com.sap.sse.landscape.mongodb.impl;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sse.common.impl.NamedImpl;
|
||||
import com.sap.sse.landscape.mongodb.Database;
|
||||
import com.sap.sse.landscape.mongodb.MongoEndpoint;
|
||||
|
||||
public class DatabaseImpl extends NamedImpl implements Database {
|
||||
private static final Logger logger = Logger.getLogger(DatabaseImpl.class.getName());
|
||||
private static final long serialVersionUID = -3816220771822620058L;
|
||||
private final MongoEndpoint endpoint;
|
||||
|
||||
@@ -22,12 +18,6 @@ public class DatabaseImpl extends NamedImpl implements Database {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drop() throws URISyntaxException {
|
||||
logger.info("Dropping database "+this);
|
||||
getMongoDatabase().drop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DatabaseImpl [endpoint=" + endpoint + "]";
|
||||
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
package com.sap.sse.landscape.mongodb.impl;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.landscape.mongodb.Database;
|
||||
|
||||
public class SimpleMongoEndpointImpl extends MongoEndpointImpl {
|
||||
private final String hostname;
|
||||
private final int port;
|
||||
private final Optional<String> replicaSetName;
|
||||
|
||||
public SimpleMongoEndpointImpl(String hostname, int port) {
|
||||
this(hostname, port, /* no replica set name */ null);
|
||||
}
|
||||
|
||||
public SimpleMongoEndpointImpl(String hostname, int port, String replicaSetName) {
|
||||
super();
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
this.replicaSetName = Optional.ofNullable(replicaSetName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI(Optional<Database> optionalDb) throws URISyntaxException {
|
||||
return getURI(optionalDb, hostname, port, replicaSetName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI(Optional<Database> optionalDb, Optional<Duration> timeoutEmptyMeaningForever) throws URISyntaxException {
|
||||
return getURI(optionalDb);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -26,6 +26,7 @@ import com.google.gwt.user.cellview.client.TextColumn;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.util.NaturalComparator;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.celltable.AbstractSortableTextColumn;
|
||||
@@ -200,7 +201,7 @@ extends TableWrapper<UserDTO, S, StringMessages, TR> {
|
||||
string.add(t.getFullName());
|
||||
string.add(t.getEmail());
|
||||
string.add(t.getCompany());
|
||||
string.add(t.getUserGroups().toString());
|
||||
Util.addAll(Util.map(t.getUserGroups(), StrippedUserGroupDTO::getName), string);
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -91,7 +91,8 @@ public class AbstractUserDetails extends Composite implements UserDetailsView {
|
||||
StrippedUserGroupDTO defaultTennant = currentUser.getDefaultTenant();
|
||||
defaultTenantUi.clear();
|
||||
int i = 0;
|
||||
for (StrippedUserGroupDTO group : Util.sortNamedCollection(currentUser.getUserGroups())) {
|
||||
for (StrippedUserGroupDTO group : Util.sortNamedCollection(currentUser.getUserGroups(),
|
||||
/* caseSensitive */ false)) {
|
||||
defaultTenantUi.addItem(group.getName(), group.getId().toString());
|
||||
if (Util.equalsWithNull(group, defaultTennant)) {
|
||||
defaultTenantUi.setSelectedIndex(i);
|
||||
|
||||
+1
-1
@@ -536,7 +536,7 @@
|
||||
<!-- GWT version detected from dependencyManagement -->
|
||||
<execution>
|
||||
<configuration>
|
||||
<extraJvmArgs>-Dgwt.persistentunitcache=false -Xmx2560m -Djava.io.tmpdir=${env.TMP} -Dgwt.watchFileChanges=false</extraJvmArgs>
|
||||
<extraJvmArgs>-Dgwt.persistentunitcache=false -Xmx4g -Djava.io.tmpdir=${env.TMP} -Dgwt.watchFileChanges=false</extraJvmArgs>
|
||||
<fragmentCount>4</fragmentCount>
|
||||
<!--
|
||||
<userAgents>chrome</userAgents>
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ fi
|
||||
JAVA_BINARY="$JAVA_HOME/bin/java"
|
||||
JAVA_VERSION_OUTPUT=$("$JAVA_BINARY" -version 2>&1)
|
||||
JAVA_VERSION=$(echo "$JAVA_VERSION_OUTPUT" | sed 's/^.* version "\(.*\)\.\(.*\)\..*".*$/\1.\2/; 1q')
|
||||
export JAVA_11_LOGGING_ARGS="-Xlog:gc+ergo*=trace:file=logs/gc_ergo.log:time:filecount=10,filesize=100000 -Xlog:gc*:file=logs/gc.log:time:filecount=10,filesize=100000"
|
||||
export JAVA_11_LOGGING_ARGS="-Xlog:gc+ergo*=trace:file=logs/gc_ergo.log:time:filecount=10,filesize=10000000 -Xlog:gc*:file=logs/gc.log:time:filecount=10,filesize=100000"
|
||||
export JAVA_11_ARGS="-Dosgi.java.profile=file://`pwd`/JavaSE-11.profile --add-modules=ALL-SYSTEM -Djavax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory -XX:ThreadPriorityPolicy=1 -XX:+UnlockExperimentalVMOptions -XX:+UseZGC ${JAVA_11_LOGGING_ARGS}"
|
||||
export JAVA_8_LOGGING_ARGS="-XX:+PrintAdaptiveSizePolicy -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
|
||||
echo JAVA_VERSION detected: $JAVA_VERSION >&2
|
||||
|
||||
Reference in New Issue
Block a user