mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-19 04:05:36 +00:00
Merge branch 'master' of ssh://sapsailing.com/home/trac/git into bug1873
This commit is contained in:
@@ -216,4 +216,10 @@ myorigin =\$myhostname.sapsailing.com
|
||||
postmap hash:${password_file_location}
|
||||
systemctl restart postfix
|
||||
rm -f "${temp_mail_properties_location}"
|
||||
}
|
||||
|
||||
setup_sshd_resilience() {
|
||||
echo "ClientAliveInterval 3
|
||||
ClientAliveCountMax 3
|
||||
GatewayPorts yes" >> /etc/ssh/sshd_config
|
||||
}
|
||||
@@ -34,6 +34,9 @@ setup_cloud_cfg_and_root_login
|
||||
build_crontab_and_setup_files "${IMAGE_TYPE}" "${GIT_COPY_USER}" "${RELATIVE_PATH_TO_GIT}"
|
||||
# setup mail
|
||||
setup_mail_sending
|
||||
# setup sshd config
|
||||
setup_sshd_resilience
|
||||
systemctl reload sshd.service
|
||||
cd /usr/local/bin
|
||||
echo $BEARER_TOKEN > /root/ssh-key-reader.token
|
||||
# add basic test page which won't cause redirect error code if used as a health check.
|
||||
|
||||
@@ -8,6 +8,8 @@ public interface RaceFetcher {
|
||||
|
||||
/**
|
||||
* Not for execution on the client; on the server, returns a <code>TrackedRace</code> object.
|
||||
* The method will not block or wait for the tracked race to appear. If it isn't found (see also
|
||||
* bug 5982) then {@code null} is returned.
|
||||
*/
|
||||
Object getTrackedRace(RegattaAndRaceIdentifier regattaNameAndRaceName);
|
||||
|
||||
|
||||
-5
@@ -9,11 +9,6 @@ public interface RaceIdentifier extends Serializable {
|
||||
|
||||
Object getRace(RaceFetcher raceFetcher);
|
||||
|
||||
/**
|
||||
* Blocks and waits if the tracked race for this race identifier doesn't exist yet.
|
||||
*/
|
||||
Object getTrackedRace(RaceFetcher raceFetcher);
|
||||
|
||||
/**
|
||||
* Immediately returns <code>null</code> if the tracked race for this race identifier doesn't exist yet.
|
||||
*/
|
||||
|
||||
-4
@@ -24,10 +24,6 @@ public class RegattaNameAndRaceName extends RegattaName implements RegattaAndRac
|
||||
return raceFetcher.getRace(this);
|
||||
}
|
||||
@Override
|
||||
public Object getTrackedRace(RaceFetcher raceFetcher) {
|
||||
return raceFetcher.getTrackedRace(this);
|
||||
}
|
||||
@Override
|
||||
public Object getExistingTrackedRace(RaceFetcher raceFetcher) {
|
||||
return raceFetcher.getExistingTrackedRace(this);
|
||||
}
|
||||
|
||||
+1
@@ -154,6 +154,7 @@ public class TracTracConnectivityParamsHandler extends AbstractRaceTrackingConne
|
||||
} else {
|
||||
final String creatorName = SessionUtils.getPrincipal().toString();
|
||||
final TracTracConfigurationImpl tracTracConfiguration = new TracTracConfigurationImpl(creatorName, tractracRace.getEvent().getName(), jsonURL,
|
||||
// FIXME bug5983: stored/live URIs should be captured in the configuration only if they were specified explicitly when the parameters were created
|
||||
(params.getLiveURI() == null ? null : params.getLiveURI().toString()),
|
||||
/* 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
|
||||
|
||||
+5
-1
@@ -219,12 +219,16 @@ public abstract class TrackedRegattaImpl implements TrackedRegatta {
|
||||
public void raceAdded(TrackedRace trackedRace) {
|
||||
synchronized (mutex) { // TODO possible improvement: only notify if trackedRace.getRace() == race; otherwise it cannot have made a difference for getExistingTrackedRace(race)...
|
||||
mutex.notifyAll();
|
||||
} // TODO can't we remove the listener again here?
|
||||
}
|
||||
}
|
||||
};
|
||||
addRaceListener(listener, Optional.empty(), /* synchronous */ false);
|
||||
try {
|
||||
synchronized (mutex) {
|
||||
if (getRegatta().getRaceByName(race.getName()) == null) {
|
||||
throw new IllegalStateException("Race "+race.getName()+" not in regatta "+getRegatta().getName()+
|
||||
"; not blocking for it to appear. It most likely won't");
|
||||
}
|
||||
result = getExistingTrackedRace(race);
|
||||
while (!interrupted && result == null) {
|
||||
try {
|
||||
|
||||
+7
-7
@@ -55,19 +55,19 @@ public class GetSixtyInchStatisticAction implements SailingAction<GetSixtyInchSt
|
||||
final RaceDefinition race = context.getRacingEventService().getRace(identifier);
|
||||
int competitors = com.sap.sse.common.Util.size(race.getCompetitors());
|
||||
legs = race.getCourse().getLegs().size();
|
||||
final DynamicTrackedRace trace = context.getRacingEventService().getTrackedRace(identifier);
|
||||
final DynamicTrackedRace trackedRace = context.getRacingEventService().getTrackedRace(identifier);
|
||||
Duration duration = null;
|
||||
Distance distance = null;
|
||||
TimePoint timePoint;
|
||||
if (trace.getEndOfRace() == null) {
|
||||
if (trackedRace.getEndOfRace() == null) {
|
||||
timePoint = MillisecondsTimePoint.now();
|
||||
duration = estimateDuration(trace, duration, timePoint);
|
||||
distance = estimateDistance(trace, distance, timePoint);
|
||||
duration = estimateDuration(trackedRace, duration, timePoint);
|
||||
distance = estimateDistance(trackedRace, distance, timePoint);
|
||||
} else {
|
||||
final Iterator<Competitor> competitorIterator = trace.getCompetitorsFromBestToWorst(trace.getEndOfRace()).iterator();
|
||||
final Iterator<Competitor> competitorIterator = trackedRace.getCompetitorsFromBestToWorst(trackedRace.getEndOfRace()).iterator();
|
||||
if (competitorIterator.hasNext()) {
|
||||
distance = trace.getDistanceTraveled(competitorIterator.next(), trace.getEndOfRace());
|
||||
duration = trace.getStartOfRace().until(trace.getEndOfRace());
|
||||
distance = trackedRace.getDistanceTraveled(competitorIterator.next(), trackedRace.getEndOfRace());
|
||||
duration = trackedRace.getStartOfRace().until(trackedRace.getEndOfRace());
|
||||
}
|
||||
}
|
||||
return new GetSixtyInchStatisticDTO(competitors, legs, duration, distance);
|
||||
|
||||
+1
-1
@@ -2486,5 +2486,5 @@ zeroBasedNumberOfWaypointForRepeatablePartEnd=Index koncového trasového bodu o
|
||||
defaultNumberOfLapsMustNotBeNegative=Výchozí počet kol nesmí být záporný.
|
||||
eitherNoneOrBothStartAndEndOfRepeatablePartMustBeSpecified=Pokud zadáte začátek opakovatelné části sekvence trasových bodů, musíte zadat i její konec.
|
||||
endOfRepeatablePartMustBeAtOfAfterStart=Konec opakovatelné části musí být za jejím začátkem.
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=Konec opakovatelné části přesahuje počet trasových bodů. Upravte konfiguraci dráhy.
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=Konec opakovatelné části přesahuje počet trasových bodů.
|
||||
configureCourse=Konfigurovat dráhu
|
||||
|
||||
+1
-1
@@ -2486,5 +2486,5 @@ zeroBasedNumberOfWaypointForRepeatablePartEnd=Índice de punto de ruta de final
|
||||
defaultNumberOfLapsMustNotBeNegative=El número predeterminado de vueltas no debe ser negativo.
|
||||
eitherNoneOrBothStartAndEndOfRepeatablePartMustBeSpecified=No se debe indicar ninguna o ambas, inicio y final, de la parte repetible de la secuencia de los puntos de ruta.
|
||||
endOfRepeatablePartMustBeAtOfAfterStart=El final de la parte repetible debe ser igual o posterior al inicio de la parte repetible.
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=El final de la parte repetible es mayor al número de waypoints.econfigureCourse
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=El final de la parte repetible es mayor al número de waypoints.
|
||||
configureCourse=Configurar rumbo
|
||||
|
||||
+1
-1
@@ -2486,5 +2486,5 @@ zeroBasedNumberOfWaypointForRepeatablePartEnd=Index des points de cheminement -
|
||||
defaultNumberOfLapsMustNotBeNegative=Le nombre de tours par défaut ne doit pas être négatif.
|
||||
eitherNoneOrBothStartAndEndOfRepeatablePartMustBeSpecified=Vous devez obligatoirement indiquer le début et la fin de la portion répétée de la séquence de points de cheminement (ou aucun des deux).
|
||||
endOfRepeatablePartMustBeAtOfAfterStart=La fin de la portion répétée doit se situer au début de la portion répétée ou après.
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=La fin de la portion répétée est supérieure au nombre de waypoints.econfigureCourse
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=La fin de la portion répétée est supérieure au nombre de points de cheminement.
|
||||
configureCourse=Configurer le parcours
|
||||
|
||||
+1
-1
@@ -2486,5 +2486,5 @@ zeroBasedNumberOfWaypointForRepeatablePartEnd=繰り返し可能順序終了変
|
||||
defaultNumberOfLapsMustNotBeNegative=ラップのデフォルト数はマイナスであってはなりません。
|
||||
eitherNoneOrBothStartAndEndOfRepeatablePartMustBeSpecified=変針点順序の繰り返し可能部分は、なしで指定するか、開始と終了の両方を指定する必要があります。
|
||||
endOfRepeatablePartMustBeAtOfAfterStart=繰り返し可能部分の終了は、繰り返し可能部分の開始以降である必要があります。
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=繰り返し可能部分の終了は、waypoints.econfigureCourse の数より大きくなります
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=繰り返し可能部分の終了は、変針点の数より大きくなります
|
||||
configureCourse=コースの設定
|
||||
|
||||
+1
-1
@@ -2486,5 +2486,5 @@ zeroBasedNumberOfWaypointForRepeatablePartEnd=Índice de waypoint de fim de sequ
|
||||
defaultNumberOfLapsMustNotBeNegative=O número padrão de voltas não pode ser negativo.
|
||||
eitherNoneOrBothStartAndEndOfRepeatablePartMustBeSpecified=Deve ser indicado o início e o fim da parte repetível da sequência de waypoint, os dois ou nenhum.
|
||||
endOfRepeatablePartMustBeAtOfAfterStart=O fim da parte repetível deve ser o mesmo que ou após o início da parte repetível.
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=O fim da parte repetível é maior que o número de waypoints.econfigureCourse
|
||||
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=O fim da parte repetível é maior que o número de waypoints.
|
||||
configureCourse=Configurar curso
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ public class QuickRanksLiveCache {
|
||||
public QuickRanksDTO get(RegattaAndRaceIdentifier raceIdentifier) {
|
||||
QuickRanksDTO result = cache.get(raceIdentifier, false);
|
||||
if (result == null) {
|
||||
TrackedRace trackedRace = service.getExistingTrackedRace(raceIdentifier);
|
||||
final TrackedRace trackedRace = service.getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
trackedRace.addListener(new Listener(raceIdentifier)); // register for all changes that may affect the quick ranks
|
||||
cache.triggerUpdate(raceIdentifier, CalculateOrPurge.CALCULATE);
|
||||
|
||||
+24
-20
@@ -662,7 +662,6 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
* Stops this service and frees its resources. In particular, caching services and threads owned by this service will be
|
||||
* notified to stop their jobs.
|
||||
*/
|
||||
//UNCLEAR
|
||||
public void stop() {
|
||||
quickRanksLiveCache.stop();
|
||||
}
|
||||
@@ -1632,7 +1631,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
|
||||
@Override
|
||||
public SimulatorResultsDTO getSimulatorResults(LegIdentifier legIdentifier) {
|
||||
DynamicTrackedRace trackedRace = getService().getTrackedRace(legIdentifier.getRaceIdentifier());
|
||||
final DynamicTrackedRace trackedRace = getService().getTrackedRace(legIdentifier.getRaceIdentifier());
|
||||
if (trackedRace == null) {
|
||||
throw new IllegalArgumentException("Race for leg " + legIdentifier + " not found!");
|
||||
}
|
||||
@@ -3346,10 +3345,12 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
|
||||
@Override
|
||||
public DynamicTrackedRace getTrackedRace(RegattaAndRaceIdentifier regattaNameAndRaceName) {
|
||||
Regatta regatta = getService().getRegattaByName(regattaNameAndRaceName.getRegattaName());
|
||||
RaceDefinition race = getRaceByName(regatta, regattaNameAndRaceName.getRaceName());
|
||||
DynamicTrackedRace trackedRace = getService().getOrCreateTrackedRegatta(regatta).getTrackedRace(race);
|
||||
getSecurityService().checkCurrentUserReadPermission(trackedRace);
|
||||
final Regatta regatta = getService().getRegattaByName(regattaNameAndRaceName.getRegattaName());
|
||||
final RaceDefinition race = getRaceByName(regatta, regattaNameAndRaceName.getRaceName());
|
||||
final DynamicTrackedRace trackedRace = getService().getOrCreateTrackedRegatta(regatta).getExistingTrackedRace(race);
|
||||
if (trackedRace != null) {
|
||||
getSecurityService().checkCurrentUserReadPermission(trackedRace);
|
||||
}
|
||||
return trackedRace;
|
||||
}
|
||||
|
||||
@@ -5637,9 +5638,9 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
public Boolean checkIfRaceIsTracking(RegattaAndRaceIdentifier race) {
|
||||
getSecurityService().checkCurrentUserReadPermission(race);
|
||||
boolean result = false;
|
||||
DynamicTrackedRace trace = getService().getTrackedRace(race);
|
||||
if (trace != null) {
|
||||
final TrackedRaceStatusEnum status = trace.getStatus().getStatus();
|
||||
DynamicTrackedRace trackedRace = getService().getTrackedRace(race);
|
||||
if (trackedRace != null) {
|
||||
final TrackedRaceStatusEnum status = trackedRace.getStatus().getStatus();
|
||||
if (status == TrackedRaceStatusEnum.LOADING || status == TrackedRaceStatusEnum.TRACKING) {
|
||||
result = true;
|
||||
}
|
||||
@@ -6387,22 +6388,25 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
|
||||
@Override
|
||||
public boolean canSliceRace(RegattaAndRaceIdentifier raceIdentifier) {
|
||||
final boolean result;
|
||||
final Regatta regatta = getService().getRegattaByName(raceIdentifier.getRegattaName());
|
||||
final Leaderboard regattaLeaderboard = getService().getLeaderboardByName(raceIdentifier.getRegattaName());
|
||||
final DynamicTrackedRace trackedRace = getService().getTrackedRace(raceIdentifier);
|
||||
getSecurityService().checkCurrentUserUpdatePermission(raceIdentifier);
|
||||
getSecurityService().checkCurrentUserUpdatePermission(regattaLeaderboard);
|
||||
getSecurityService().checkCurrentUserUpdatePermission(regatta);
|
||||
|
||||
final boolean result;
|
||||
if (regatta == null || !(regattaLeaderboard instanceof RegattaLeaderboard) || trackedRace == null
|
||||
|| trackedRace.getStartOfTracking() == null || !isSmartphoneTrackingEnabled(trackedRace)) {
|
||||
if (trackedRace == null ) {
|
||||
result = false;
|
||||
} else {
|
||||
final Pair<RaceColumn, Fleet> raceColumnAndFleetOfRaceToSlice = regattaLeaderboard
|
||||
.getRaceColumnAndFleet(trackedRace);
|
||||
result = (raceColumnAndFleetOfRaceToSlice != null); // is the TrackedRace associated to the given
|
||||
// RegattaLeaderboard?
|
||||
getSecurityService().checkCurrentUserUpdatePermission(raceIdentifier);
|
||||
getSecurityService().checkCurrentUserUpdatePermission(regattaLeaderboard);
|
||||
getSecurityService().checkCurrentUserUpdatePermission(regatta);
|
||||
if (regatta == null || !(regattaLeaderboard instanceof RegattaLeaderboard) || trackedRace == null
|
||||
|| trackedRace.getStartOfTracking() == null || !isSmartphoneTrackingEnabled(trackedRace)) {
|
||||
result = false;
|
||||
} else {
|
||||
final Pair<RaceColumn, Fleet> raceColumnAndFleetOfRaceToSlice = regattaLeaderboard
|
||||
.getRaceColumnAndFleet(trackedRace);
|
||||
result = (raceColumnAndFleetOfRaceToSlice != null); // is the TrackedRace associated to the given
|
||||
// RegattaLeaderboard?
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+16
-11
@@ -2105,11 +2105,13 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
|
||||
final List<DynamicTrackedRace> trackedRaces = new ArrayList<>();
|
||||
if (selectedRaces != null && !selectedRaces.isEmpty()) {
|
||||
for (RaceDTO raceDTO : selectedRaces) {
|
||||
DynamicTrackedRace trackedRace = getTrackedRace(raceDTO.getRaceIdentifier());
|
||||
// In case the user selected a distinct set of races, we want the call to completely fail if
|
||||
// tracking wind isn't allowed for at least one race
|
||||
getSecurityService().checkCurrentUserUpdatePermission(trackedRace);
|
||||
trackedRaces.add(trackedRace);
|
||||
final DynamicTrackedRace trackedRace = getTrackedRace(raceDTO.getRaceIdentifier());
|
||||
if (trackedRace != null) {
|
||||
// In case the user selected a distinct set of races, we want the call to completely fail if
|
||||
// tracking wind isn't allowed for at least one race
|
||||
getSecurityService().checkCurrentUserUpdatePermission(trackedRace);
|
||||
trackedRaces.add(trackedRace);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (DynamicTrackedRace race : getAllTrackedRaces()) {
|
||||
@@ -2601,11 +2603,13 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
|
||||
public RaceDTO setStartTimeReceivedForRace(RaceIdentifier raceIdentifier, Date newStartTimeReceived) {
|
||||
RegattaNameAndRaceName regattaAndRaceIdentifier = new RegattaNameAndRaceName(raceIdentifier.getRegattaName(),
|
||||
raceIdentifier.getRaceName());
|
||||
DynamicTrackedRace trackedRace = getService().getTrackedRace(regattaAndRaceIdentifier);
|
||||
getSecurityService().checkCurrentUserUpdatePermission(trackedRace);
|
||||
trackedRace.setStartTimeReceived(
|
||||
newStartTimeReceived == null ? null : new MillisecondsTimePoint(newStartTimeReceived));
|
||||
return baseDomainFactory.createRaceDTO(getService(), false, regattaAndRaceIdentifier, trackedRace);
|
||||
final DynamicTrackedRace trackedRace = getService().getTrackedRace(regattaAndRaceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
getSecurityService().checkCurrentUserUpdatePermission(trackedRace);
|
||||
trackedRace.setStartTimeReceived(
|
||||
newStartTimeReceived == null ? null : new MillisecondsTimePoint(newStartTimeReceived));
|
||||
}
|
||||
return trackedRace == null ? null : baseDomainFactory.createRaceDTO(getService(), false, regattaAndRaceIdentifier, trackedRace);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2958,6 +2962,8 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
|
||||
throw new ServiceException(serverStringMessages.get(locale, "slicingRaceColumnAlreadyUsedThe"));
|
||||
}
|
||||
final DynamicTrackedRace trackedRaceToSlice = getService().getTrackedRace(raceIdentifier);
|
||||
// If tracked race isn't found, a NullPointerException will be thrown next, and that's okay because
|
||||
// it's a bit unusual to not find a race that is just about to be sliced. We couldn't continue anyway.
|
||||
final TimePoint startOfTrackingOfRaceToSlice = trackedRaceToSlice.getStartOfTracking();
|
||||
final TimePoint endOfTrackingOfRaceToSlice = trackedRaceToSlice.getEndOfTracking();
|
||||
if (sliceFrom == null || sliceTo == null || startOfTrackingOfRaceToSlice.after(sliceFrom)
|
||||
@@ -2997,7 +3003,6 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
|
||||
hasFinishingTime = false;
|
||||
hasFinishedTime = false;
|
||||
}
|
||||
|
||||
// Only wind fixes in the new tracking interval as well as the best fallback fixes are added to the new RaceLog
|
||||
final LogEventTimeRangeWithFallbackFilter<RaceLogWindFixEvent> windFixEvents = new LogEventTimeRangeWithFallbackFilter<>(
|
||||
timeRange);
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=Počet instancí MongoDB, které se mají spustit
|
||||
priority=Priorita
|
||||
votes=Hlasy
|
||||
instanceType=Typ instance
|
||||
instanceName=Název instance
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=Zadali jste kladný počet instancí, které se mají spustit.
|
||||
youHaveToProvideANonNegativePriority=Zadaná hodnota priority nesmí být záporná.
|
||||
youHaveToProvideANonNegativeNumberOfVotes=Zadaný počet hlasů nesmí být záporný.
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=Všechny procesy byly úspěšně pře
|
||||
dnsNameAlreadyInUse=Název DNS se již používá
|
||||
errorArchivingMongoDBTo=Chyba při archivaci MongoDB sady replik k sadě replik Mongo {0}: {1}
|
||||
optionalSessionToken=Token relace (volitelný)
|
||||
reverseProxies=Reverzní proxy servery
|
||||
rotateHttpdLogs=Rotovat logy httpd
|
||||
successfullyRotatedHttpdLogsOnInstance=Rotace logů Apache Httpd proběhla úspěšně u instance: {0}
|
||||
invalidOperationForThisProxy=Tuto operaci nelze u této instance provést.
|
||||
pleaseProvideNonEmptyNameAndAZ=Zadejte neprázdný název (UTF-8) a AZ.
|
||||
success=úspěch
|
||||
availabilityZone=Zóna dostupnosti
|
||||
runOnExisting=Spustit na existující běžící instanci
|
||||
publicIp=Veřejná IP adresa
|
||||
privateIp=Soukromá IP adresa
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=Antal MongoDB-instanser, der skal startes
|
||||
priority=Prioritet
|
||||
votes=Stemmer
|
||||
instanceType=Instanstype
|
||||
instanceName=Instansnavn
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=Du skal angive et positivt antal instanser, der skal startes.
|
||||
youHaveToProvideANonNegativePriority=Du skal angive en ikke-negativ prioritet.
|
||||
youHaveToProvideANonNegativeNumberOfVotes=Du skal angive et ikke-negativt antal stemmer.
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=Alle processer blev flyttet væk fra v
|
||||
dnsNameAlreadyInUse=DNS-navn er allerede i brug
|
||||
errorArchivingMongoDBTo=Fejl ved arkivering af replikasæts MongoDB til Monogo-replikasættet {0}: {1}
|
||||
optionalSessionToken=Sessionstoken (valgfrit)
|
||||
reverseProxies=Omvendte proxyer
|
||||
rotateHttpdLogs=Roter httpd-logge
|
||||
successfullyRotatedHttpdLogsOnInstance=Roterede Apache-Httpd-logge på instans: {0}
|
||||
invalidOperationForThisProxy=Du kan ikke udføre denne handling på denne instans
|
||||
pleaseProvideNonEmptyNameAndAZ=Angiv et ikke-tomt navn (UTF-8) og et AZ.
|
||||
success=uden fejl
|
||||
availabilityZone=Tilgængelighedszone
|
||||
runOnExisting=Kør på en eksisterende, igangværende instans
|
||||
publicIp=Offentlig IP-adresse
|
||||
privateIp=Privat IP-adresse
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=Cantidad de instancias MongoDB para iniciar
|
||||
priority=Prioridad
|
||||
votes=Votos
|
||||
instanceType=Tipo de instancia
|
||||
instanceName=Nombre de la instancia
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=Debe indicar un número positivo de instancias para iniciar.
|
||||
youHaveToProvideANonNegativePriority=Debe indicar una prioridad no negativa.
|
||||
youHaveToProvideANonNegativeNumberOfVotes=Debe indicar un número no negativo de votos.
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=Todos los procesos movidos correctamen
|
||||
dnsNameAlreadyInUse=Nombre de DNS ya en uso
|
||||
errorArchivingMongoDBTo=Error al archivar conjunto de réplica MongoDB en conjunto de réplica Mongo {0}: {1}
|
||||
optionalSessionToken=Token de sesión (opcional)
|
||||
reverseProxies=Anular proxies
|
||||
rotateHttpdLogs=Rotar logs httpd
|
||||
successfullyRotatedHttpdLogsOnInstance=Se han rotado correctamente los logs de Apache httpd en la instancia: {0}
|
||||
invalidOperationForThisProxy=No se puede realizar esta operación en esta instancia
|
||||
pleaseProvideNonEmptyNameAndAZ=Introduzca un nombre no vacío (UTF-8) y una zona de disponibilidad.
|
||||
success=correcto
|
||||
availabilityZone=Zona de disponibilidad
|
||||
runOnExisting=Ejecutar en una instancia existente y en funcionamiento
|
||||
publicIp=Dirección IP pública
|
||||
privateIp=Dirección IP privada
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=Nombre d''instances MongoDB à lancer
|
||||
priority=Priorité
|
||||
votes=Votes
|
||||
instanceType=Type d''instance
|
||||
instanceName=Nom de l''instance
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=Vous devez indiquer un nombre positif d''instances à lancer.
|
||||
youHaveToProvideANonNegativePriority=Vous devez indiquer une priorité non négative.
|
||||
youHaveToProvideANonNegativeNumberOfVotes=Vous devez indiquer une nombre de votes non négatif.
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=Processus correctement déplacés depu
|
||||
dnsNameAlreadyInUse=Nom DNS déjà utilisé
|
||||
errorArchivingMongoDBTo=Erreur lors de l''archivage de l''ensemble de réplicas MongoDB dans l''ensemble de réplicas Mongo {0} : {1}
|
||||
optionalSessionToken=Jeton de session (facultatif)
|
||||
reverseProxies=Proxies inverses
|
||||
rotateHttpdLogs=Effectuer la rotation des journaux httpd
|
||||
successfullyRotatedHttpdLogsOnInstance=Rotation des journaux httpd Apache correctement effectuée sur l''instance : {0}
|
||||
invalidOperationForThisProxy=Vous ne pouvez pas effectuer cette opération sur cette instance.
|
||||
pleaseProvideNonEmptyNameAndAZ=Veuillez fournir un nom (UTF-8) et une zone de disponibilité.
|
||||
success=réussite
|
||||
availabilityZone=Zone de disponibilité
|
||||
runOnExisting=Exécuter sur une instance existante et en cours d''exécution
|
||||
publicIp=Adresse IP publique
|
||||
privateIp=Adresse IP privée
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=Numero di istanze MongoDB da avviare
|
||||
priority=Priorità
|
||||
votes=Voti
|
||||
instanceType=Tipo di istanza
|
||||
instanceName=Nome istanza
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=È necessario fornire un numero positivo di istanze da avviare
|
||||
youHaveToProvideANonNegativePriority=È necessario fornire una priorità non negativa
|
||||
youHaveToProvideANonNegativeNumberOfVotes=È necessario fornire un numero di voti non negativo
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=Spostamento di tutti i processi dall''
|
||||
dnsNameAlreadyInUse=Nome DNS già in uso
|
||||
errorArchivingMongoDBTo=Errore di archiviazione del MongoDB del set di replica nel set di replica Mongo {0}: {1}
|
||||
optionalSessionToken=Token di sessione (opzionale)
|
||||
reverseProxies=Proxy inversi
|
||||
rotateHttpdLogs=Ruota i registri httpd
|
||||
successfullyRotatedHttpdLogsOnInstance=I registri Httpd Apache sono stati ruotati correttamente nell''istanza: {0}
|
||||
invalidOperationForThisProxy=Non è possibile eseguire questa operazione in questa istanza
|
||||
pleaseProvideNonEmptyNameAndAZ=Fornire un nome non vuoto (UTF-8) e un AZ.
|
||||
success=esito positivo
|
||||
availabilityZone=Zona di disponibilità
|
||||
runOnExisting=Esegui in un''istanza esistente in esecuzione
|
||||
publicIp=Indirizzo IP pubblico
|
||||
privateIp=Indirizzo IP privato
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=開始する MongoDB インスタンスの数
|
||||
priority=priority
|
||||
votes=votes
|
||||
instanceType=インスタンスタイプ
|
||||
instanceName=インスタンス名
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=開始するインスタンスはプラスの数で指定する必要があります。
|
||||
youHaveToProvideANonNegativePriority=マイナスではない priority を指定する必要があります。
|
||||
youHaveToProvideANonNegativeNumberOfVotes=マイナスでない数の votes を指定する必要があります。
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=すべてのプロセスがホスト {
|
||||
dnsNameAlreadyInUse=DNS 名はすでに使用中です
|
||||
errorArchivingMongoDBTo=複製セットの MongoDB を Mongo 複製セット {0} にアーカイブする際にエラーが発生: {1}
|
||||
optionalSessionToken=セッショントークン (オプション)
|
||||
reverseProxies=リバースプロキシ
|
||||
rotateHttpdLogs=httpd ログのローテーション
|
||||
successfullyRotatedHttpdLogsOnInstance=インスタンスでの Apache httpd ログのローテーションに成功しました: {0}
|
||||
invalidOperationForThisProxy=この処理はこのインスタンスでは実行できません
|
||||
pleaseProvideNonEmptyNameAndAZ=空でない名前 (UTF-8) と A~Z の 1 文字を指定してください。
|
||||
success=成功
|
||||
availabilityZone=可用性ゾーン
|
||||
runOnExisting=既存の起動済みインスタンスで実行
|
||||
publicIp=パブリック IP アドレス
|
||||
privateIp=プライベート IP アドレス
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=Número de instâncias MongoDB para iniciar
|
||||
priority=Prioridade
|
||||
votes=Votos
|
||||
instanceType=Tipo de instância
|
||||
instanceName=Nome da instância
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=Você tem que fornecer um número positivo de instâncias para iniciar.
|
||||
youHaveToProvideANonNegativePriority=Você tem que fornecer uma prioridade não negativa.
|
||||
youHaveToProvideANonNegativeNumberOfVotes=Você tem que fornecer um número não negativo de votos.
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=Todos os processos movidos com êxito
|
||||
dnsNameAlreadyInUse=Nome de DNS já em utilização
|
||||
errorArchivingMongoDBTo=Erro ao arquivar MongoDB de conjunto de réplicas para o conjunto de réplicas Mongo {0}: {1}
|
||||
optionalSessionToken=Token de sessão (opcional)
|
||||
reverseProxies=Estornar proxies
|
||||
rotateHttpdLogs=Rotacionar logs httpd
|
||||
successfullyRotatedHttpdLogsOnInstance=Logs Httpd Apache rotacionados com êxito na instância: {0}
|
||||
invalidOperationForThisProxy=Você não pode efetuar esta operação nesta instância
|
||||
pleaseProvideNonEmptyNameAndAZ=Forneça um nome que não esteja em branco (UTF-8) e um AZ.
|
||||
success=êxito
|
||||
availabilityZone=Zona de disponibilidade
|
||||
runOnExisting=Executar em uma instância em execução existente
|
||||
publicIp=Endereço IP público
|
||||
privateIp=Endereço IP privado
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=Число инстанций MongoDB для за
|
||||
priority=Приоритет
|
||||
votes=Голоса
|
||||
instanceType=Тип инстанции
|
||||
instanceName=Имя инстанции
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=Введите положительное число инстанций для запуска.
|
||||
youHaveToProvideANonNegativePriority=Введите неотрицательный приоритет.
|
||||
youHaveToProvideANonNegativeNumberOfVotes=Введите неотрицательное число голосов.
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=Все процессы успешно
|
||||
dnsNameAlreadyInUse=Имя DNS уже используется
|
||||
errorArchivingMongoDBTo=Ошибка при архивации MongoDB набора реплик в набор реплик Mongo {0}: {1}
|
||||
optionalSessionToken=Маркер сеанса (опциональный)
|
||||
reverseProxies=Обратные прокси
|
||||
rotateHttpdLogs=Ротировать журналы httpd
|
||||
successfullyRotatedHttpdLogsOnInstance=Журналы Httpd Apache успешно ротированы в инстанции: {0}
|
||||
invalidOperationForThisProxy=Вы не можете выполнить эту операцию в данной инстанции
|
||||
pleaseProvideNonEmptyNameAndAZ=Укажите непустое имя (UTF-8) и AZ.
|
||||
success=успешно
|
||||
availabilityZone=Зона доступности
|
||||
runOnExisting=Выполнить в существующей запущенной инстанции
|
||||
publicIp=Общедоступный IP-адрес
|
||||
privateIp=Частный IP-адрес
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=Število instanc podatkovne baze MongoDB za zagon
|
||||
priority=Prioriteta
|
||||
votes=Glasovi
|
||||
instanceType=Vrsta instance
|
||||
instanceName=Ime instance
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=Za zagon morate navesti pozitivno število instanc.
|
||||
youHaveToProvideANonNegativePriority=Navesti morate nenegativno prioriteto.
|
||||
youHaveToProvideANonNegativeNumberOfVotes=Navesti morate nenegativno število glasov.
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=Vsi procesi uspešno premaknjeni iz go
|
||||
dnsNameAlreadyInUse=Ime DNS je že v uporabi
|
||||
errorArchivingMongoDBTo=Napaka pri arhiviranju MongoDB niza replik v niz replik Mongo {0}: {1}
|
||||
optionalSessionToken=Žeton seje (izbirno)
|
||||
reverseProxies=Razveljavitev posredniških strežnikov
|
||||
rotateHttpdLogs=Zasuk zapisnikov httpd
|
||||
successfullyRotatedHttpdLogsOnInstance=Uspešno zasukani zapisniki Apache Httpd na instanci: {0}
|
||||
invalidOperationForThisProxy=Tega postopka ni mogoče izvajati na tej instanci
|
||||
pleaseProvideNonEmptyNameAndAZ=Navedite ima, ki ni prazno (UTF-8), in AZ.
|
||||
success=uspeh
|
||||
availabilityZone=Območje razpoložljivosti
|
||||
runOnExisting=Izvajanje na obstoječi, izvajajoči se instanci
|
||||
publicIp=Javni IP-naslov
|
||||
privateIp=Zasebni IP-naslov
|
||||
|
||||
+11
@@ -41,6 +41,7 @@ numberOfMongoInstancesToLaunch=启动的 MongoDB 实例的数量
|
||||
priority=优先级
|
||||
votes=投票
|
||||
instanceType=实例类型
|
||||
instanceName=实例名称
|
||||
youHaveToProvideAPositiveNumberOfInstancesToLaunch=对于要启动的实例,您必须提供为正的数量。
|
||||
youHaveToProvideANonNegativePriority=您必须提供非负优先级。
|
||||
youHaveToProvideANonNegativeNumberOfVotes=您必须提供非负票数。
|
||||
@@ -155,3 +156,13 @@ successfullyMovedAllProcessesAwayFromHost=已成功将所有流程移离主机 {
|
||||
dnsNameAlreadyInUse=DNS 名称已在使用中
|
||||
errorArchivingMongoDBTo=归档复本集的 MongoDB 到 Mongo 复本集 {0} 出错:{1}
|
||||
optionalSessionToken=会话令牌(可选)
|
||||
reverseProxies=反向代理
|
||||
rotateHttpdLogs=轮换 httpd 日志
|
||||
successfullyRotatedHttpdLogsOnInstance=已成功轮换实例上的 Apache Httpd 日志:{0}
|
||||
invalidOperationForThisProxy=无法在该实例上执行此操作
|
||||
pleaseProvideNonEmptyNameAndAZ=请提供非空名称 (UTF-8) 和 AZ。
|
||||
success=成功
|
||||
availabilityZone=可用区
|
||||
runOnExisting=在现有的运行中实例上运行
|
||||
publicIp=公共 IP 地址
|
||||
privateIp=专用 IP 地址
|
||||
|
||||
-11
@@ -10,7 +10,6 @@ import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracAdapterFactory;
|
||||
import com.sap.sailing.server.interfaces.RacingEventService;
|
||||
import com.sap.sse.InvalidDateException;
|
||||
@@ -135,16 +134,6 @@ public abstract class SailingServerHttpServlet extends HttpServlet {
|
||||
return timePoint;
|
||||
}
|
||||
|
||||
protected TrackedRace getTrackedRace(HttpServletRequest req) {
|
||||
Regatta regatta = getRegatta(req);
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
TrackedRace trackedRace = null;
|
||||
if (regatta != null && race != null) {
|
||||
trackedRace = getService().getOrCreateTrackedRegatta(regatta).getTrackedRace(race);
|
||||
}
|
||||
return trackedRace;
|
||||
}
|
||||
|
||||
protected TypeBasedServiceFinderFactory getServiceFinderFactory() {
|
||||
return serviceFinderFactory;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1429,7 +1429,7 @@ public class RegattasResource extends AbstractSailingServerResource {
|
||||
if (race == null) {
|
||||
response = getBadRaceErrorResponse(regattaName, raceName);
|
||||
} else {
|
||||
DynamicTrackedRace trackedRace = getService().getTrackedRace(regatta, race);
|
||||
final DynamicTrackedRace trackedRace = getService().getTrackedRace(regatta, race);
|
||||
if (trackedRace != null) {
|
||||
TargetTimeInfo targetTime;
|
||||
try {
|
||||
|
||||
+4
-1
@@ -107,7 +107,10 @@ public class WindResource extends AbstractSailingServerResource {
|
||||
RegattaNameAndRaceName identifier = new RegattaNameAndRaceName(regattaName, raceName);
|
||||
// add wind only to those races the subject is permitted to update
|
||||
if (getSecurityService().hasCurrentUserUpdatePermission(identifier)) {
|
||||
result.add(new RaceIdentifierAndTrackedRace(identifier, getService().getTrackedRace(identifier)));
|
||||
final DynamicTrackedRace trackedRace = getService().getTrackedRace(identifier);
|
||||
if (trackedRace != null) {
|
||||
result.add(new RaceIdentifierAndTrackedRace(identifier, trackedRace));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
+26
-23
@@ -365,31 +365,34 @@ public class ExpeditionAllInOneImporter {
|
||||
securityService.checkCurrentUserExplicitPermissions(service.getRegatta(new RegattaName(regattaNameAndleaderboardName)), DefaultActions.UPDATE);
|
||||
securityService.checkCurrentUserExplicitPermissions(service.getLeaderboardByName(regattaNameAndleaderboardName), DefaultActions.UPDATE);
|
||||
if (importMode == ImportMode.NEW_COMPETITOR) {
|
||||
securityService.checkCurrentUserExplicitPermissions(service.getTrackedRace(new RegattaNameAndRaceName(regattaNameAndleaderboardName, trackedRaceName)), DefaultActions.UPDATE);
|
||||
final TimePointsOfFirstAndLastFix firstAndLastFixAt = importFixes(filenameWithSuffix, fileItem, jsonHolderForGpsFixImport, jsonHolderForSensorFixImport, errors);
|
||||
ensureEventLongEnough(firstAndLastFixAt.getFirstFixAt(), firstAndLastFixAt.getLastFixAt(), eventId);
|
||||
final Iterable<RaceColumn> raceColumns = regattaLeaderboard.getRaceColumns();
|
||||
if (Util.isEmpty(raceColumns)) {
|
||||
return new ImporterResult(serverStringMessages.get(uiLocale, "allInOneErrorInvalidRace"));
|
||||
}
|
||||
try {
|
||||
for (RaceColumn raceColumn : raceColumns) {
|
||||
final Iterable<? extends Fleet> fleets = raceColumn.getFleets();
|
||||
if (Util.size(fleets) != 1) {
|
||||
return new ImporterResult(serverStringMessages.get(uiLocale, "allInOneErrorSplitFleetNotSupported"));
|
||||
final DynamicTrackedRace trackedRace = service.getTrackedRace(new RegattaNameAndRaceName(regattaNameAndleaderboardName, trackedRaceName));
|
||||
if (trackedRace != null) {
|
||||
securityService.checkCurrentUserExplicitPermissions(trackedRace, DefaultActions.UPDATE);
|
||||
final TimePointsOfFirstAndLastFix firstAndLastFixAt = importFixes(filenameWithSuffix, fileItem, jsonHolderForGpsFixImport, jsonHolderForSensorFixImport, errors);
|
||||
ensureEventLongEnough(firstAndLastFixAt.getFirstFixAt(), firstAndLastFixAt.getLastFixAt(), eventId);
|
||||
final Iterable<RaceColumn> raceColumns = regattaLeaderboard.getRaceColumns();
|
||||
if (Util.isEmpty(raceColumns)) {
|
||||
return new ImporterResult(serverStringMessages.get(uiLocale, "allInOneErrorInvalidRace"));
|
||||
}
|
||||
try {
|
||||
for (RaceColumn raceColumn : raceColumns) {
|
||||
final Iterable<? extends Fleet> fleets = raceColumn.getFleets();
|
||||
if (Util.size(fleets) != 1) {
|
||||
return new ImporterResult(serverStringMessages.get(uiLocale, "allInOneErrorSplitFleetNotSupported"));
|
||||
}
|
||||
final Fleet fleet = fleets.iterator().next();
|
||||
DynamicTrackedRace trackedRaceForColumn = (DynamicTrackedRace) raceColumn.getTrackedRace(fleet);
|
||||
if (trackedRaceForColumn == null) {
|
||||
trackedRaceForColumn = trackRace(regattaLeaderboard, raceColumn, fleet);
|
||||
}
|
||||
trackedRaces.add(trackedRaceForColumn);
|
||||
raceNameRaceColumnNameFleetnameList
|
||||
.add(new Triple<>(trackedRaceForColumn.getRaceIdentifier().getRaceName(),
|
||||
raceColumn.getName(), fleet.getName()));
|
||||
}
|
||||
final Fleet fleet = fleets.iterator().next();
|
||||
DynamicTrackedRace trackedRaceForColumn = (DynamicTrackedRace) raceColumn.getTrackedRace(fleet);
|
||||
if (trackedRaceForColumn == null) {
|
||||
trackedRaceForColumn = trackRace(regattaLeaderboard, raceColumn, fleet);
|
||||
}
|
||||
trackedRaces.add(trackedRaceForColumn);
|
||||
raceNameRaceColumnNameFleetnameList
|
||||
.add(new Triple<>(trackedRaceForColumn.getRaceIdentifier().getRaceName(),
|
||||
raceColumn.getName(), fleet.getName()));
|
||||
} catch (Exception e) {
|
||||
throw new AllInOneImportException(e, errors);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new AllInOneImportException(e, errors);
|
||||
}
|
||||
} else if (importMode == ImportMode.NEW_RACE) {
|
||||
// When uploading files with identical name, the second RaceColumn will be named with the upload time in its name
|
||||
|
||||
+23
-21
@@ -28,32 +28,34 @@ public class TrackFilesExportPostServlet extends SailingServerHttpServlet {
|
||||
private static final Logger log = Logger.getLogger(TrackFilesExportPostServlet.class.toString());
|
||||
|
||||
private TrackedRace getTrackedRace(String regattaString, String raceString) {
|
||||
Regatta regatta = getService().getRegattaByName(regattaString);
|
||||
if (regatta == null)
|
||||
return null;
|
||||
RaceDefinition race = regatta.getRaceByName(raceString);
|
||||
if (race == null)
|
||||
return null;
|
||||
|
||||
return getService().getTrackedRace(regatta, race);
|
||||
final TrackedRace result;
|
||||
final Regatta regatta = getService().getRegattaByName(regattaString);
|
||||
if (regatta == null) {
|
||||
result = null;
|
||||
} else {
|
||||
final RaceDefinition race = regatta.getRaceByName(raceString);
|
||||
if (race == null) {
|
||||
result = null;
|
||||
} else {
|
||||
result = getService().getTrackedRace(regatta, race);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<TrackedRace> getTrackedRaces(String[] regattaRaces) {
|
||||
List<TrackedRace> races = new ArrayList<TrackedRace>();
|
||||
|
||||
final List<TrackedRace> races = new ArrayList<TrackedRace>();
|
||||
for (String regattaRace : regattaRaces) {
|
||||
String[] split = regattaRace.split(":");
|
||||
if (split.length == 0)
|
||||
continue;
|
||||
String regattaString = split[0];
|
||||
String raceString = split[1];
|
||||
TrackedRace trackedRace = getTrackedRace(regattaString, raceString);
|
||||
if (trackedRace == null)
|
||||
continue;
|
||||
|
||||
races.add(trackedRace);
|
||||
final String[] split = regattaRace.split(":");
|
||||
if (split.length != 0) {
|
||||
final String regattaString = split[0];
|
||||
final String raceString = split[1];
|
||||
final TrackedRace trackedRace = getTrackedRace(regattaString, raceString);
|
||||
if (trackedRace != null) {
|
||||
races.add(trackedRace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return races;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -144,17 +144,17 @@ public abstract class AbstractWindImporter {
|
||||
if (uploadRequest.races.size() > 0) {
|
||||
for (RegattaAndRaceIdentifier raceEntry : uploadRequest.races) {
|
||||
DynamicTrackedRace trackedRace = service.getTrackedRace(raceEntry);
|
||||
SecurityUtils.getSubject()
|
||||
.checkPermission(trackedRace.getIdentifier().getStringPermission(DefaultActions.UPDATE));
|
||||
if (trackedRace != null) {
|
||||
SecurityUtils.getSubject()
|
||||
.checkPermission(trackedRace.getIdentifier().getStringPermission(DefaultActions.UPDATE));
|
||||
trackedRaces.add(trackedRace);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Regatta regatta : service.getAllRegattas()) {
|
||||
for (RaceDefinition raceDefinition : regatta.getAllRaces()) {
|
||||
final DynamicTrackedRace trackedRace = service.getTrackedRegatta(regatta).getTrackedRace(raceDefinition);
|
||||
if (SecurityUtils.getSubject()
|
||||
final DynamicTrackedRace trackedRace = service.getTrackedRegatta(regatta).getExistingTrackedRace(raceDefinition);
|
||||
if (trackedRace != null && SecurityUtils.getSubject()
|
||||
.isPermitted(trackedRace.getIdentifier().getStringPermission(DefaultActions.UPDATE))) {
|
||||
trackedRaces.add(trackedRace);
|
||||
}
|
||||
|
||||
+9
-2
@@ -161,11 +161,18 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
@Override
|
||||
RaceDefinition getRace(RegattaAndRaceIdentifier raceIdentifier);
|
||||
|
||||
/**
|
||||
* Looks for a {@link DynamicTrackedRace} inside the {@link TrackedRegatta} identified by {@code regatta},
|
||||
* keyed by the race definition {@code race}. If no such race is found, e.g., because it is still in its "loading"
|
||||
* phase and the {@link TrackedRace} hasn't been created and added to the {@link TrackedRegatta} yet, or because
|
||||
* it is in the process of being removed, with the {@link TrackedRace} already gone but the {@link RaceDefinition}
|
||||
* still available (see also bug 5982), this method will return {@code null} without any waiting or blocking.
|
||||
*/
|
||||
DynamicTrackedRace getTrackedRace(Regatta regatta, RaceDefinition race);
|
||||
|
||||
/**
|
||||
* When the regatta, tracked regatta and race definition are found, this method waits for the
|
||||
* tracked race to appear.
|
||||
* This method does not for the tracked race to appear. If any of regatta, race definition or tracked race are not
|
||||
* found, {@code null} is returned.
|
||||
*/
|
||||
DynamicTrackedRace getTrackedRace(RegattaAndRaceIdentifier raceIdentifier);
|
||||
|
||||
|
||||
+3
-1
@@ -475,6 +475,8 @@ public class ImportMasterDataOperation extends
|
||||
DynamicTrackedRace trackedRace = toState
|
||||
.getTrackedRace((RegattaAndRaceIdentifier) raceIdentifier);
|
||||
raceColumn.setTrackedRace(fleet, trackedRace);
|
||||
// in case the TrackedRace wasn't found (see also bug 5982), at least record the race identifier
|
||||
raceColumn.setRaceIdentifier(fleet, raceIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -708,7 +710,7 @@ public class ImportMasterDataOperation extends
|
||||
RaceHandle raceHandle = toState.addRace(/* default */ null, paramToStartTracking, /* do not wait */ -1);
|
||||
final RaceDefinition race = raceHandle.getRace(RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS);
|
||||
if (race != null) {
|
||||
final DynamicTrackedRace trackedRace = raceHandle.getTrackedRegatta().getTrackedRace(race);
|
||||
final DynamicTrackedRace trackedRace = raceHandle.getTrackedRegatta().getTrackedRace(race); // wait/block for tracked race to show up
|
||||
result.add(trackedRace);
|
||||
ensureOwnership(trackedRace.getIdentifier(), securityService);
|
||||
creationCount.addOneTrackedRace(race.getId().toString());
|
||||
|
||||
+7
-4
@@ -3054,7 +3054,7 @@ Replicator {
|
||||
* already have been removed by the stopAllTrackersForWhichRaceIsLastReachable(...) above; maybe a
|
||||
* Java memory model idiosyncrasy with the queue thread not "seeing" the change to dataTrackers?).
|
||||
* We must make sure to not block its execution, e.g., by synchronization, because otherwise
|
||||
* the the removedTrackedRegatta(regatta) call below may not return, either, as it waits for
|
||||
* the removedTrackedRegatta(regatta) call below may not return, either, as it waits for
|
||||
* tasks it may enqueue after the task enqueued here. See bug 5879.
|
||||
*/
|
||||
trackedRegatta.removeTrackedRace(trackedRace, Optional.of(
|
||||
@@ -3104,6 +3104,9 @@ Replicator {
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME bug5982: when the TrackedRace is removed already, queries for the RaceDefinition would still be satisfied up to this point, with a RaceDefinition that is about to disappear;
|
||||
// FIXME bug5982: no TrackedRace will ever appear again for that RaceDefinition; we should consider introducing a locking pattern around the transaction of removing TrackedRace+RaceDefinition
|
||||
// FIXME bug5982: and synchronize accordingly with TrackedRegattaImpl.getTrackedRace(RaceDefinition).
|
||||
// remove the race from the (default) regatta if the regatta is not persistently stored
|
||||
regatta.removeRace(race);
|
||||
if (!regatta.isPersistent() && Util.isEmpty(regatta.getAllRaces())) {
|
||||
@@ -3170,7 +3173,7 @@ Replicator {
|
||||
|
||||
@Override
|
||||
public DynamicTrackedRace getTrackedRace(Regatta regatta, RaceDefinition race) {
|
||||
return getOrCreateTrackedRegatta(regatta).getTrackedRace(race);
|
||||
return getOrCreateTrackedRegatta(regatta).getExistingTrackedRace(race);
|
||||
}
|
||||
|
||||
private DynamicTrackedRace getExistingTrackedRace(Regatta regatta, RaceDefinition race) {
|
||||
@@ -3234,9 +3237,9 @@ Replicator {
|
||||
if (regatta != null) {
|
||||
DynamicTrackedRegatta trackedRegatta = regattaTrackingCache.get(regatta);
|
||||
if (trackedRegatta != null) {
|
||||
RaceDefinition race = getRace(raceIdentifier);
|
||||
RaceDefinition race = regatta.getRaceByName(raceIdentifier.getRaceName());
|
||||
if (race != null) {
|
||||
result = trackedRegatta.getTrackedRace(race);
|
||||
result = trackedRegatta.getExistingTrackedRace(race);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -404,7 +404,7 @@ public class SimulationServiceImpl implements SimulationService {
|
||||
});
|
||||
}
|
||||
if (!legListeners.containsKey(legIdentifier.getRaceIdentifier())) {
|
||||
TrackedRace trackedRace = racingEventService.getTrackedRace(legIdentifier);
|
||||
final TrackedRace trackedRace = racingEventService.getTrackedRace(legIdentifier);
|
||||
if (trackedRace != null) {
|
||||
LegChangeListener listener = new LegChangeListener(trackedRace);
|
||||
legListeners.put(legIdentifier.getRaceIdentifier(), listener);
|
||||
|
||||
Reference in New Issue
Block a user