mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-17 11:19:15 +00:00
bug6288: use TimePoint instead of long millis in LiveContentCheckResult and SailingServer.getLiveContent
Change SailingServer.getLiveContent(long) to accept a TimePoint and refactor LiveContentCheckResult to hold a TimePoint (checkedAt) rather than a long (checkedAtMillis), matching how TimePoint is used elsewhere in the SailingService[Write] API. Also adds Javadoc to getLiveContent. Serialization: - GWT RPC now writes/reads the TimePoint as an object (TimePoint is GWT-serializable and already used across the RPC boundary). - JSON keeps the long millisecond value (or null) on the wire under the unchanged checkedAtMillis key; the deserializer wraps it back into a TimePoint via TimePoint.of(...). Regenerated serialVersionUID for the changed field layout of LiveContentCheckResult. Assisted-By: Claude (claude-4.8-opus)
This commit is contained in:
+8
-6
@@ -5,25 +5,27 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* Describes live tracked races found in one or more application replica sets at one instant in time. An empty
|
||||
* {@link #getReplicaSetsWithLiveContent() list} means that no live content was found.
|
||||
*/
|
||||
public final class LiveContentCheckResult implements Serializable {
|
||||
private static final long serialVersionUID = 4259503344851123760L;
|
||||
private final long checkedAtMillis;
|
||||
private static final long serialVersionUID = 3100475095484004645L;
|
||||
private final TimePoint checkedAt;
|
||||
private final List<ReplicaSetLiveContent> replicaSetsWithLiveContent;
|
||||
|
||||
public LiveContentCheckResult(final long checkedAtMillis,
|
||||
public LiveContentCheckResult(final TimePoint checkedAt,
|
||||
final Iterable<ReplicaSetLiveContent> replicaSetsWithLiveContent) {
|
||||
this.checkedAtMillis = checkedAtMillis;
|
||||
this.checkedAt = checkedAt;
|
||||
final List<ReplicaSetLiveContent> replicaSetsWithLiveContentCopy = new ArrayList<>();
|
||||
replicaSetsWithLiveContent.forEach(replicaSetsWithLiveContentCopy::add);
|
||||
this.replicaSetsWithLiveContent = Collections.unmodifiableList(replicaSetsWithLiveContentCopy);
|
||||
}
|
||||
|
||||
public long getCheckedAtMillis() {
|
||||
return checkedAtMillis;
|
||||
public TimePoint getCheckedAt() {
|
||||
return checkedAt;
|
||||
}
|
||||
|
||||
public List<ReplicaSetLiveContent> getReplicaSetsWithLiveContent() {
|
||||
|
||||
+7
-4
@@ -15,13 +15,16 @@ import com.sap.sailing.landscape.common.LiveContentAwareOperationResult;
|
||||
import com.sap.sailing.landscape.common.LiveContentCheckResult;
|
||||
import com.sap.sailing.landscape.common.RaceLiveContent;
|
||||
import com.sap.sailing.landscape.common.ReplicaSetLiveContent;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class TestLiveContentValueTypes {
|
||||
private static final TimePoint CHECKED_AT = TimePoint.of(42L);
|
||||
|
||||
@Test
|
||||
public void testEmptyCheckResult() {
|
||||
final LiveContentCheckResult result = new LiveContentCheckResult(42L, Collections.emptyList());
|
||||
final LiveContentCheckResult result = new LiveContentCheckResult(CHECKED_AT, Collections.emptyList());
|
||||
assertFalse(result.hasLiveContent());
|
||||
assertEquals(42L, result.getCheckedAtMillis());
|
||||
assertEquals(CHECKED_AT, result.getCheckedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -31,7 +34,7 @@ public class TestLiveContentValueTypes {
|
||||
Collections.singleton(race));
|
||||
final ReplicaSetLiveContent replicaSet = new ReplicaSetLiveContent("replica-set",
|
||||
Collections.singleton(event));
|
||||
final LiveContentCheckResult result = new LiveContentCheckResult(42L, Collections.singleton(replicaSet));
|
||||
final LiveContentCheckResult result = new LiveContentCheckResult(CHECKED_AT, Collections.singleton(replicaSet));
|
||||
assertTrue(result.hasLiveContent());
|
||||
assertEquals("race", result.getReplicaSetsWithLiveContent().get(0).getEventsWithLiveContent().get(0)
|
||||
.getRacesWithLiveContent().get(0).getRaceName());
|
||||
@@ -40,7 +43,7 @@ public class TestLiveContentValueTypes {
|
||||
|
||||
@Test
|
||||
public void testOperationResultInvariants() {
|
||||
final LiveContentCheckResult conflict = new LiveContentCheckResult(42L, Collections.emptyList());
|
||||
final LiveContentCheckResult conflict = new LiveContentCheckResult(CHECKED_AT, Collections.emptyList());
|
||||
assertTrue(LiveContentAwareOperationResult.success("ok").isSuccessful());
|
||||
assertFalse(LiveContentAwareOperationResult.liveContentConflict(conflict).isSuccessful());
|
||||
assertThrows(IllegalArgumentException.class, () -> LiveContentAwareOperationResult.liveContentConflict(null));
|
||||
|
||||
+4
-3
@@ -9,11 +9,12 @@ import com.google.gwt.user.client.rpc.SerializationStreamReader;
|
||||
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
|
||||
import com.sap.sailing.landscape.common.LiveContentCheckResult;
|
||||
import com.sap.sailing.landscape.common.ReplicaSetLiveContent;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public final class LiveContentCheckResult_CustomFieldSerializer extends CustomFieldSerializer<LiveContentCheckResult> {
|
||||
public static void serialize(final SerializationStreamWriter writer, final LiveContentCheckResult instance)
|
||||
throws SerializationException {
|
||||
writer.writeLong(instance.getCheckedAtMillis());
|
||||
writer.writeObject(instance.getCheckedAt());
|
||||
writer.writeInt(instance.getReplicaSetsWithLiveContent().size());
|
||||
for (final ReplicaSetLiveContent replicaSet : instance.getReplicaSetsWithLiveContent()) {
|
||||
writer.writeObject(replicaSet);
|
||||
@@ -22,13 +23,13 @@ public final class LiveContentCheckResult_CustomFieldSerializer extends CustomFi
|
||||
|
||||
public static LiveContentCheckResult instantiate(final SerializationStreamReader reader)
|
||||
throws SerializationException {
|
||||
final long checkedAtMillis = reader.readLong();
|
||||
final TimePoint checkedAt = (TimePoint) reader.readObject();
|
||||
final int replicaSetCount = reader.readInt();
|
||||
final List<ReplicaSetLiveContent> replicaSets = new ArrayList<>(replicaSetCount);
|
||||
for (int i = 0; i < replicaSetCount; i++) {
|
||||
replicaSets.add((ReplicaSetLiveContent) reader.readObject());
|
||||
}
|
||||
return new LiveContentCheckResult(checkedAtMillis, replicaSets);
|
||||
return new LiveContentCheckResult(checkedAt, replicaSets);
|
||||
}
|
||||
|
||||
public static void deserialize(final SerializationStreamReader reader, final LiveContentCheckResult instance) {
|
||||
|
||||
+3
-3
@@ -596,14 +596,14 @@ public class LandscapeServiceImpl implements LandscapeService {
|
||||
final Iterable<AwsApplicationReplicaSet<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>>> applicationReplicaSets,
|
||||
final String bearerToken) throws Exception {
|
||||
final String effectiveBearerToken = getEffectiveBearerToken(bearerToken);
|
||||
final long checkedAtMillis = TimePoint.now().asMillis();
|
||||
final TimePoint checkedAt = TimePoint.now();
|
||||
final List<ReplicaSetLiveContent> replicaSetsWithLiveContent = new ArrayList<>();
|
||||
for (final AwsApplicationReplicaSet<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> replicaSet : applicationReplicaSets) {
|
||||
final SailingServer server = sailingServerFactoryTracker.getService().getSailingServer(new URL("https", replicaSet.getHostname(), "/"), effectiveBearerToken);
|
||||
final LiveContentCheckResult replicaSetResult = server.getLiveContent(checkedAtMillis);
|
||||
final LiveContentCheckResult replicaSetResult = server.getLiveContent(checkedAt);
|
||||
replicaSetsWithLiveContent.addAll(replicaSetResult.getReplicaSetsWithLiveContent());
|
||||
}
|
||||
return new LiveContentCheckResult(checkedAtMillis, replicaSetsWithLiveContent);
|
||||
return new LiveContentCheckResult(checkedAt, replicaSetsWithLiveContent);
|
||||
}
|
||||
|
||||
private void checkForLiveContentUnlessForced(
|
||||
|
||||
+20
-1
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.RemoteSailingServerReference;
|
||||
import com.sap.sailing.domain.common.DataImportProgress;
|
||||
import com.sap.sailing.landscape.common.LiveContentCheckResult;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.security.util.SecuredServer;
|
||||
import com.sap.sse.shared.json.JsonDeserializationException;
|
||||
|
||||
@@ -56,7 +57,25 @@ public interface SailingServer extends SecuredServer {
|
||||
*/
|
||||
Iterable<EventBase> getEvents() throws Exception;
|
||||
|
||||
LiveContentCheckResult getLiveContent(long checkedAtMillis) throws Exception;
|
||||
/**
|
||||
* Asks the remote server which of its {@link EventBase events} were tracking live content (races being tracked)
|
||||
* at a given instant in time, reusing the {@code /v1/livecontent} endpoint. This is a Java facade over that REST
|
||||
* call and is executed with this object's authentication information (see the {@link SailingServer class
|
||||
* documentation}); the remote endpoint requires {@code MANAGE} permission on the {@code AWS} landscape object.
|
||||
*
|
||||
* @param checkedAt
|
||||
* the instant for which live content shall be determined. A race counts as live content if it was being
|
||||
* tracked at that instant. Pass {@link TimePoint#now()} to find out what is live right now.
|
||||
* @return a {@link LiveContentCheckResult} describing, per replica set, the events and races that were tracked
|
||||
* live at {@code checkedAt}. The result is never {@code null}; an empty
|
||||
* {@link LiveContentCheckResult#getReplicaSetsWithLiveContent() list} (equivalently,
|
||||
* {@link LiveContentCheckResult#hasLiveContent()} returning {@code false}) means no live content was found.
|
||||
* @throws Exception
|
||||
* if the remote request cannot be sent or its response cannot be parsed or deserialized; concrete
|
||||
* implementations may throw more specific exceptions such as {@link IOException},
|
||||
* {@link ClientProtocolException}, {@link ParseException} or {@link JsonDeserializationException}.
|
||||
*/
|
||||
LiveContentCheckResult getLiveContent(TimePoint checkedAt) throws Exception;
|
||||
|
||||
MasterDataImportResult importMasterData(SailingServer from, Iterable<UUID> leaderboardGroupIds, boolean override,
|
||||
boolean compress, boolean exportWind, boolean exportDeviceConfigs,
|
||||
|
||||
+3
-2
@@ -11,6 +11,7 @@ import com.sap.sailing.landscape.common.LiveContentCheckResult;
|
||||
import com.sap.sailing.landscape.common.RaceLiveContent;
|
||||
import com.sap.sailing.landscape.common.ReplicaSetLiveContent;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.LiveContentCheckResultJsonSerializer;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.shared.json.JsonDeserializationException;
|
||||
import com.sap.sse.shared.json.JsonDeserializer;
|
||||
|
||||
@@ -45,8 +46,8 @@ public final class LiveContentCheckResultJsonDeserializer implements JsonDeseria
|
||||
replicaSets.add(new ReplicaSetLiveContent(
|
||||
(String) serializedReplicaSet.get(LiveContentCheckResultJsonSerializer.REPLICA_SET_NAME), events));
|
||||
}
|
||||
return new LiveContentCheckResult(
|
||||
((Number) object.get(LiveContentCheckResultJsonSerializer.CHECKED_AT_MILLIS)).longValue(), replicaSets);
|
||||
final Long checkedAtMillis = asLong(object.get(LiveContentCheckResultJsonSerializer.CHECKED_AT_MILLIS));
|
||||
return new LiveContentCheckResult(checkedAtMillis == null ? null : TimePoint.of(checkedAtMillis), replicaSets);
|
||||
}
|
||||
|
||||
private Long asLong(final Object value) {
|
||||
|
||||
+2
-1
@@ -27,7 +27,8 @@ public final class LiveContentCheckResultJsonSerializer implements JsonSerialize
|
||||
@Override
|
||||
public JSONObject serialize(final LiveContentCheckResult liveContentCheckResult) {
|
||||
final JSONObject result = new JSONObject();
|
||||
result.put(CHECKED_AT_MILLIS, liveContentCheckResult.getCheckedAtMillis());
|
||||
result.put(CHECKED_AT_MILLIS, liveContentCheckResult.getCheckedAt() == null ? null
|
||||
: liveContentCheckResult.getCheckedAt().asMillis());
|
||||
final JSONArray replicaSets = new JSONArray();
|
||||
for (final ReplicaSetLiveContent replicaSet : liveContentCheckResult.getReplicaSetsWithLiveContent()) {
|
||||
final JSONObject serializedReplicaSet = new JSONObject();
|
||||
|
||||
+3
-2
@@ -48,6 +48,7 @@ import com.sap.sailing.server.gateway.jaxrs.api.EventsResource;
|
||||
import com.sap.sailing.server.gateway.jaxrs.api.LeaderboardGroupsResource;
|
||||
import com.sap.sailing.server.gateway.jaxrs.api.LeaderboardsResource;
|
||||
import com.sap.sailing.server.gateway.jaxrs.api.LiveContentResource;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sailing.server.gateway.jaxrs.api.MasterDataImportResource;
|
||||
import com.sap.sailing.server.gateway.jaxrs.api.RemoteServerReferenceResource;
|
||||
import com.sap.sailing.server.gateway.serialization.LeaderboardGroupConstants;
|
||||
@@ -130,10 +131,10 @@ public class SailingServerImpl extends SecuredServerImpl implements SailingServe
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveContentCheckResult getLiveContent(final long checkedAtMillis) throws ClientProtocolException, IOException,
|
||||
public LiveContentCheckResult getLiveContent(final TimePoint checkedAt) throws ClientProtocolException, IOException,
|
||||
ParseException, JsonDeserializationException {
|
||||
final URL liveContentUrl = new URL(getBaseUrl(), GATEWAY_URL_PREFIX + LiveContentResource.V1_LIVE_CONTENT +
|
||||
"?" + LiveContentResource.CHECKED_AT_MILLIS_QUERY_PARAM + "=" + checkedAtMillis);
|
||||
"?" + LiveContentResource.CHECKED_AT_MILLIS_QUERY_PARAM + "=" + checkedAt.asMillis());
|
||||
final HttpGet getLiveContent = new HttpGet(liveContentUrl.toString());
|
||||
final JSONObject jsonResponse = (JSONObject) getJsonParsedResponse(getLiveContent).getA();
|
||||
return new LiveContentCheckResultJsonDeserializer().deserialize(jsonResponse);
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ public final class LiveContentResource extends AbstractSailingServerResource {
|
||||
if (!eventsWithLiveContent.isEmpty()) {
|
||||
replicaSetsWithLiveContent.add(new ReplicaSetLiveContent(ServerInfo.getName(), eventsWithLiveContent));
|
||||
}
|
||||
final LiveContentCheckResult result = new LiveContentCheckResult(checkedAt.asMillis(),
|
||||
final LiveContentCheckResult result = new LiveContentCheckResult(checkedAt,
|
||||
replicaSetsWithLiveContent);
|
||||
return Response.ok(streamingOutput(new LiveContentCheckResultJsonSerializer().serialize(result))).build();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user