mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-11 14:50:56 +00:00
Merge branch 'master' into newhome
Conflicts: java/com.sap.sailing.gwt.ui/SailingGWT.launch (added Search.html entry point to SailingGWT.launch)
This commit is contained in:
commit
6f1979b756
16 files changed
+616
-41
No files matched your search
@@ -22,6 +22,7 @@ import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResultBase;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
@@ -556,5 +557,25 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
*/
|
||||
Util.Pair<Iterable<EventBase>, Exception> updateRemoteServerEventCacheSynchronously(RemoteSailingServerReference ref);
|
||||
|
||||
/**
|
||||
* Searches the content of this server, not that of any remote servers referenced by any {@link RemoteSailingServerReference}s.
|
||||
*/
|
||||
Result<LeaderboardSearchResult> search(KeywordQuery query);
|
||||
|
||||
/**
|
||||
* Searches a specific remote server whose reference has the {@link RemoteSailingServerReference#getName() name}
|
||||
* <code>remoteServerReferenceName</code>. If a remote server reference with that name is not known,
|
||||
* <code>null</code> is returned. Otherwise, a non-<code>null</code> and possibly empty search result set is
|
||||
* returned.
|
||||
*/
|
||||
Result<LeaderboardSearchResultBase> searchRemotely(String remoteServerReferenceName, KeywordQuery query);
|
||||
|
||||
/**
|
||||
* References to remote servers may be dead or alive. This is internally determined by regularly polling those
|
||||
* servers for their events list. If the events list cannot be successfully retrieved, the server is considered "dead."
|
||||
* This method returns the "live" server references.
|
||||
*/
|
||||
Iterable<RemoteSailingServerReference> getLiveRemoteServerReferences();
|
||||
|
||||
RemoteSailingServerReference getRemoteServerReferenceByName(String remoteServerReferenceName);
|
||||
}
|
||||
+23
-25
@@ -5,28 +5,18 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResultBase;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class RegattaSearchResultRanker implements Comparator<LeaderboardSearchResult> {
|
||||
private final TrackedRegattaRegistry trackedRegattaRegistry;
|
||||
|
||||
protected RegattaSearchResultRanker(RacingEventService racingEventService) {
|
||||
this.trackedRegattaRegistry = racingEventService;
|
||||
}
|
||||
|
||||
public class LeaderboardSearchResultBaseRanker<T extends LeaderboardSearchResultBase> implements Comparator<T> {
|
||||
@Override
|
||||
public int compare(LeaderboardSearchResult o1, LeaderboardSearchResult o2) {
|
||||
Regatta r1 = o1.getRegatta();
|
||||
Regatta r2 = o2.getRegatta();
|
||||
TrackedRegatta trackedR1 = r1 == null ? null : trackedRegattaRegistry.getTrackedRegatta(r1);
|
||||
TrackedRegatta trackedR2 = r2 == null ? null : trackedRegattaRegistry.getTrackedRegatta(r2);
|
||||
public int compare(T o1, T o2) {
|
||||
TrackedRegatta trackedR1 = getTrackedRegatta(o1);
|
||||
TrackedRegatta trackedR2 = getTrackedRegatta(o2);
|
||||
final int result;
|
||||
if (trackedR1 == null) {
|
||||
if (trackedR2 == null) {
|
||||
@@ -44,16 +34,8 @@ public class RegattaSearchResultRanker implements Comparator<LeaderboardSearchRe
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int compareByEarliestStartOfATrackedRace(TrackedRegatta trackedR1, TrackedRegatta trackedR2) {
|
||||
assert trackedR1 != null;
|
||||
assert trackedR2 != null;
|
||||
TimePoint earliestTrackedRaceInR1 = getEarliestTrackedRace(trackedR1);
|
||||
TimePoint earliestTrackedRaceInR2 = getEarliestTrackedRace(trackedR2);
|
||||
return Util.compareToWithNull(earliestTrackedRaceInR1, earliestTrackedRaceInR2, /* nullIsLess */ false);
|
||||
}
|
||||
|
||||
private TimePoint getEarliestTrackedRace(TrackedRegatta trackedRegatta) {
|
||||
|
||||
protected TimePoint getEarliestTrackedRace(TrackedRegatta trackedRegatta) {
|
||||
List<TimePoint> startOfTrackingTimes = new ArrayList<>();
|
||||
for (TrackedRace trackedRace : trackedRegatta.getTrackedRaces()) {
|
||||
if (trackedRace.getStartOfTracking() != null) {
|
||||
@@ -68,4 +50,20 @@ public class RegattaSearchResultRanker implements Comparator<LeaderboardSearchRe
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected int compareByEarliestStartOfATrackedRace(TrackedRegatta trackedR1, TrackedRegatta trackedR2) {
|
||||
assert trackedR1 != null;
|
||||
assert trackedR2 != null;
|
||||
TimePoint earliestTrackedRaceInR1 = getEarliestTrackedRace(trackedR1);
|
||||
TimePoint earliestTrackedRaceInR2 = getEarliestTrackedRace(trackedR2);
|
||||
return Util.compareToWithNull(earliestTrackedRaceInR1, earliestTrackedRaceInR2, /* nullIsLess */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can't know a tracked regatta if we only have a {@link LeaderboardSearchResultBase} which doesn't reference a
|
||||
* real {@link Regatta} object.
|
||||
*/
|
||||
protected TrackedRegatta getTrackedRegatta(T o1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.server.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class LeaderboardSearchResultRanker extends LeaderboardSearchResultBaseRanker<LeaderboardSearchResult> {
|
||||
private final TrackedRegattaRegistry trackedRegattaRegistry;
|
||||
|
||||
protected LeaderboardSearchResultRanker(RacingEventService racingEventService) {
|
||||
this.trackedRegattaRegistry = racingEventService;
|
||||
}
|
||||
|
||||
protected TrackedRegatta getTrackedRegatta(LeaderboardSearchResult o1) {
|
||||
Regatta r1 = o1.getRegatta();
|
||||
TrackedRegatta trackedR1 = r1 == null ? null : trackedRegattaRegistry.getTrackedRegatta(r1);
|
||||
return trackedR1;
|
||||
}
|
||||
}
|
||||
+73
-1
@@ -1,12 +1,16 @@
|
||||
package com.sap.sailing.server.impl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -28,6 +32,10 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
@@ -40,6 +48,7 @@ import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResultBase;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnInSeries;
|
||||
@@ -135,6 +144,11 @@ import com.sap.sailing.server.OperationExecutionListener;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
import com.sap.sailing.server.Replicator;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardSearchResultBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
|
||||
import com.sap.sailing.server.masterdata.DataImportLockWithProgress;
|
||||
import com.sap.sailing.server.operationaltransformation.AddCourseArea;
|
||||
import com.sap.sailing.server.operationaltransformation.AddDefaultRegatta;
|
||||
@@ -174,6 +188,7 @@ import com.sap.sailing.util.impl.NamedReentrantReadWriteLock;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.search.KeywordQuery;
|
||||
import com.sap.sse.common.search.Result;
|
||||
import com.sap.sse.common.search.ResultImpl;
|
||||
|
||||
public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport, RegattaListener, LeaderboardRegistry, Replicator {
|
||||
private static final Logger logger = Logger.getLogger(RacingEventServiceImpl.class.getName());
|
||||
@@ -881,6 +896,16 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
mongoObjectFactory.storeSailingServer(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<RemoteSailingServerReference> getLiveRemoteServerReferences() {
|
||||
return remoteSailingServerSet.getLiveRemoteServerReferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteSailingServerReference getRemoteServerReferenceByName(String remoteServerReferenceName) {
|
||||
return remoteSailingServerSet.getServerReferenceByName(remoteServerReferenceName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.sap.sse.common.Util.Pair<Iterable<EventBase>, Exception> updateRemoteServerEventCacheSynchronously(RemoteSailingServerReference ref) {
|
||||
@@ -2594,6 +2619,53 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
|
||||
@Override
|
||||
public Result<LeaderboardSearchResult> search(KeywordQuery query) {
|
||||
return new RegattaByKeywordSearchService().search(this, query);
|
||||
long start = System.currentTimeMillis();
|
||||
logger.info("Searching local server for "+query);
|
||||
Result<LeaderboardSearchResult> result = new RegattaByKeywordSearchService().search(this, query);
|
||||
logger.fine("Search for "+query+" took "+(System.currentTimeMillis()-start)+"ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<LeaderboardSearchResultBase> searchRemotely(String remoteServerReferenceName, KeywordQuery query) {
|
||||
long start = System.currentTimeMillis();
|
||||
ResultImpl<LeaderboardSearchResultBase> result = null;
|
||||
RemoteSailingServerReference remoteRef = remoteSailingServerSet.getServerReferenceByName(remoteServerReferenceName);
|
||||
if (remoteRef == null) {
|
||||
result = null;
|
||||
} else {
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
try {
|
||||
final URL eventsURL = new URL(remoteRef.getURL(), "sailingserver/api/v1/search?q="+URLEncoder.encode(query.toString(), "UTF-8"));
|
||||
logger.info("Searching remote server "+remoteRef+" for "+query);
|
||||
URLConnection urlConnection = eventsURL.openConnection();
|
||||
urlConnection.connect();
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
|
||||
JSONParser parser = new JSONParser();
|
||||
Object eventsAsObject = parser.parse(bufferedReader);
|
||||
final LeaderboardGroupBaseJsonDeserializer leaderboardGroupBaseJsonDeserializer = new LeaderboardGroupBaseJsonDeserializer();
|
||||
LeaderboardSearchResultBaseJsonDeserializer deserializer = new LeaderboardSearchResultBaseJsonDeserializer(
|
||||
new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(
|
||||
DomainFactory.INSTANCE)), leaderboardGroupBaseJsonDeserializer),
|
||||
leaderboardGroupBaseJsonDeserializer);
|
||||
result = new ResultImpl<LeaderboardSearchResultBase>(query, new LeaderboardSearchResultBaseRanker<LeaderboardSearchResultBase>());
|
||||
JSONArray hitsAsJsonArray = (JSONArray) eventsAsObject;
|
||||
for (Object hitAsObject : hitsAsJsonArray) {
|
||||
JSONObject hitAsJson = (JSONObject) hitAsObject;
|
||||
LeaderboardSearchResultBase hit = deserializer.deserialize(hitAsJson);
|
||||
result.addHit(hit);
|
||||
}
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
bufferedReader.close();
|
||||
}
|
||||
}
|
||||
} catch (IOException | ParseException e) {
|
||||
logger.log(Level.INFO, "Exception trying to fetch events from remote server "+remoteRef+": "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
logger.fine("Remote search on "+remoteRef+" for "+query+" took "+(System.currentTimeMillis()-start)+"ms");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -33,7 +33,7 @@ import com.sap.sse.common.search.ResultImpl;
|
||||
*/
|
||||
public class RegattaByKeywordSearchService {
|
||||
Result<LeaderboardSearchResult> search(final RacingEventService racingEventService, KeywordQuery query) {
|
||||
ResultImpl<LeaderboardSearchResult> result = new ResultImpl<>(query, new RegattaSearchResultRanker(racingEventService));
|
||||
ResultImpl<LeaderboardSearchResult> result = new ResultImpl<>(query, new LeaderboardSearchResultRanker(racingEventService));
|
||||
final Map<Leaderboard, Event> eventForLeaderboard = new HashMap<>();
|
||||
final Map<Leaderboard, Set<LeaderboardGroup>> leaderboardGroupsForLeaderboard = new HashMap<>();
|
||||
AbstractListFilter<Leaderboard> leaderboardFilter = new AbstractListFilter<Leaderboard>() {
|
||||
|
||||
+24
-2
@@ -6,8 +6,10 @@ import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -22,7 +24,6 @@ import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.RemoteSailingServerReference;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
|
||||
@@ -30,6 +31,7 @@ import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserial
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
/**
|
||||
* A set of {@link RemoteSailingServerReference}s including a cache of their {@link EventBase events} that is
|
||||
@@ -44,7 +46,8 @@ public class RemoteSailingServerSet {
|
||||
private static final Logger logger = Logger.getLogger(RemoteSailingServerSet.class.getName());
|
||||
|
||||
/**
|
||||
* Holds the {@link Event} objects for the events of all registered sailing server instances.
|
||||
* Holds the remote server references managed by this set. Keys are the
|
||||
* {@link RemoteSailingServerReference#getName() names} of the server references.
|
||||
*/
|
||||
private final ConcurrentHashMap<String, RemoteSailingServerReference> remoteSailingServers;
|
||||
|
||||
@@ -76,6 +79,14 @@ public class RemoteSailingServerSet {
|
||||
triggerAsynchronousEventCacheUpdate(ref);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If this set has a {@link RemoteSailingServerReference} whose {@link RemoteSailingServerReference#getName() name} equals
|
||||
* <code>name</code>, it is returned. Otherwise, <code>null</code> is returned.
|
||||
*/
|
||||
public RemoteSailingServerReference getServerReferenceByName(String name) {
|
||||
return remoteSailingServers.get(name);
|
||||
}
|
||||
|
||||
private void triggerAsynchronousEventCacheUpdate(final RemoteSailingServerReference ref) {
|
||||
new Thread("Event Cache Updater for remote server "+ref) {
|
||||
@@ -150,4 +161,15 @@ public class RemoteSailingServerSet {
|
||||
}
|
||||
return updateRemoteServerEventCacheSynchronously(ref);
|
||||
}
|
||||
|
||||
public Iterable<RemoteSailingServerReference> getLiveRemoteServerReferences() {
|
||||
List<RemoteSailingServerReference> result = new ArrayList<>();
|
||||
for (Map.Entry<RemoteSailingServerReference, Pair<Iterable<EventBase>, Exception>> e : cachedEventsForRemoteSailingServers.entrySet()) {
|
||||
if (e.getValue().getB() == null) {
|
||||
// no exception; reference considered live
|
||||
result.add(e.getKey());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user