- Implemented loading and storing of a 'isStandaloneServer' attribute of a new SailingServerConfiguration domain object.

- Implemented a tab in the admin console for showing static server information and dynamic server configuration
- refactoring of static BuildVersion class into more generic ServerInfo class
This commit is contained in:
fmittag committed 2015-09-02 00:37:41 +02:00
1 parent aa8bc4b7b2
commit b43786d728
34 files changed
+457 -73

No files matched your search

@@ -16,6 +16,7 @@ public enum Permission implements com.sap.sse.security.shared.Permission {
MANAGE_STRUCTURE_IMPORT_URLS,
MANAGE_MEDIA,
MANAGE_SAILING_SERVER_INSTANCES,
MANAGE_LOCAL_SERVER_INSTANCE,
MANAGE_REPLICATION,
MANAGE_MASTERDATA_IMPORT,
MANAGE_DEVICE_CONFIGURATION,
@@ -16,6 +16,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaRegistry;
import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.base.SailingServerConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
import com.sap.sailing.domain.common.RaceIdentifier;
@@ -109,6 +110,8 @@ public interface DomainObjectFactory {
*/
void loadLeaderboardGroupLinksForEvents(EventResolver eventResolver, LeaderboardGroupResolver leaderboardGroupResolver);
SailingServerConfiguration loadServerConfiguration();
Iterable<RemoteSailingServerReference> loadAllRemoteSailingServerReferences();
Regatta loadRegatta(String name, TrackedRegattaRegistry trackedRegattaRegistry);
@@ -10,6 +10,7 @@ import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.base.SailingServerConfiguration;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
@@ -93,6 +94,8 @@ public interface MongoObjectFactory {
*/
void removeEvent(Serializable id);
void storeServerConfiguration(SailingServerConfiguration serverConfiguration);
/**
* Stores a registered sailing server
* @param serves the servers to store
@@ -43,7 +43,12 @@ public enum CollectionNames {
* Stores the registered sailing servers.
*/
SAILING_SERVERS,
/**
* Stores the settings of the server instance.
*/
SERVER,
/**
* Stores regatta definitions including their series layout and fleets and race columns. Regattas can reference
* the event from the {@link #EVENTS} collection to which they belong.
@@ -35,11 +35,11 @@ import com.mongodb.util.JSON;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.race.CompetitorResults;
import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventRestoreFactory;
import com.sap.sailing.domain.abstractlog.race.RaceLogFinishPositioningConfirmedEvent;
@@ -102,6 +102,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaRegistry;
import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.base.SailingServerConfiguration;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.Waypoint;
@@ -115,6 +116,7 @@ import com.sap.sailing.domain.base.impl.EventImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.RemoteSailingServerReferenceImpl;
import com.sap.sailing.domain.base.impl.SailingServerConfigurationImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.VenueImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
@@ -930,8 +932,26 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
return result;
}
@Override
public SailingServerConfiguration loadServerConfiguration() {
SailingServerConfiguration result;
DBCollection serverCollection = database.getCollection(CollectionNames.SERVER.name());
DBObject theServer = serverCollection.findOne();
if (theServer != null) {
result = loadServerConfiguration(theServer);
} else {
// create a default configuration
result = new SailingServerConfigurationImpl(false);
}
return result;
}
private RemoteSailingServerReference loadSailingSever(DBObject serverDBObject) {
private SailingServerConfiguration loadServerConfiguration(DBObject serverDBObject) {
boolean isStandaloneServer = (Boolean) serverDBObject.get(FieldNames.SERVER_IS_STANDALONE.name());
return new SailingServerConfigurationImpl(isStandaloneServer);
}
private RemoteSailingServerReference loadRemoteSailingSever(DBObject serverDBObject) {
RemoteSailingServerReference result = null;
String name = (String) serverDBObject.get(FieldNames.SERVER_NAME.name());
String urlAsString = (String) serverDBObject.get(FieldNames.SERVER_URL.name());
@@ -950,8 +970,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
DBCollection serverCollection = database.getCollection(CollectionNames.SAILING_SERVERS.name());
try {
for (DBObject o : serverCollection.find()) {
if (loadSailingSever(o) != null) {
result.add(loadSailingSever(o));
if (loadRemoteSailingSever(o) != null) {
result.add(loadRemoteSailingSever(o));
}
}
} catch (Exception e) {
@@ -109,10 +109,13 @@ public enum FieldNames {
REGATTA_LOG_REVOKED_REASON, REGATTA_LOG_COMPETITOR_ID, REGATTA_LOG_DEVICE_MAPPING_EVENT_ID, REGATTA_LOG_CLOSING_TIMEPOINT,
REGATTA_LOG_FROM, REGATTA_LOG_TO, REGATTA_LOG_EVENT,
// sailing server
// remote server reference fields
SERVER_NAME,
SERVER_URL,
// local server instance fields
SERVER_IS_STANDALONE,
// configurations
CONFIGURATION_MATCHER, CONFIGURATION_CONFIG, CONFIGURATION_MATCHER_ID, CONFIGURATION_MATCHER_TYPE, CONFIGURATION_MATCHER_CLIENTS,
CONFIGURATION_CONFIG_ALLOWED_COURSE_AREA_NAMES, CONFIGURATION_CONFIG_MIN_ROUNDS, CONFIGURATION_CONFIG_MAX_ROUNDS, CONFIGURATION_CONFIG_RESULTS_MAIL,
@@ -19,14 +19,14 @@ import com.mongodb.DBObject;
import com.mongodb.WriteConcern;
import com.mongodb.util.JSON;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogFinishPositioningConfirmedEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogFinishPositioningListChangedEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogFlagEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
@@ -37,8 +37,8 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent;
import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent;
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogCloseOpenEndedDeviceMappingEvent;
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDefineMarkEvent;
@@ -68,6 +68,7 @@ import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.base.SailingServerConfiguration;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.Waypoint;
@@ -501,6 +502,19 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
leaderboardGroupCollection.update(query, update, /* upsert */ true, /* multi */ false, WriteConcern.SAFE);
}
@Override
public void storeServerConfiguration(SailingServerConfiguration serverConfiguration) {
DBCollection serverCollection = database.getCollection(CollectionNames.SERVER.name());
DBObject newServerConfig = new BasicDBObject();
newServerConfig.put(FieldNames.SERVER_IS_STANDALONE.name(), serverConfiguration.isStandaloneServer());
DBObject currentServerConfig = serverCollection.findOne();
if(currentServerConfig != null) {
serverCollection.update(currentServerConfig, newServerConfig, /* upsrt */ true, /* multi */ false, WriteConcern.SAFE);
} else {
serverCollection.save(newServerConfig);
}
}
@Override
public void storeSailingServer(RemoteSailingServerReference server) {
DBCollection serverCollection = database.getCollection(CollectionNames.SAILING_SERVERS.name());
@@ -0,0 +1,15 @@
package com.sap.sailing.domain.base;
import java.io.Serializable;
/**
* Represents the configuration of an (local) instance of a sailing server.
*
* @author Frank
*
*/
public interface SailingServerConfiguration extends Serializable {
boolean isStandaloneServer();
void setStandaloneServer(boolean isStandaloneServer);
}
@@ -0,0 +1,24 @@
package com.sap.sailing.domain.base.impl;
import com.sap.sailing.domain.base.SailingServerConfiguration;
public class SailingServerConfigurationImpl implements SailingServerConfiguration {
private static final long serialVersionUID = -639945748229124558L;
/** indicates if the server is running in standalone mode or not */
private boolean isStandaloneServer;
public SailingServerConfigurationImpl(boolean isStandaloneServer) {
this.isStandaloneServer = isStandaloneServer;
}
@Override
public boolean isStandaloneServer() {
return isStandaloneServer;
}
@Override
public void setStandaloneServer(boolean isStandaloneServer) {
this.isStandaloneServer = isStandaloneServer;
}
}
@@ -209,9 +209,13 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<MasterDataImportPanel>(masterDataImportPanel),
getStringMessages().masterDataImportPanel(), Permission.MANAGE_MASTERDATA_IMPORT);
RemoteSailingServerInstancesManagementPanel sailingServerInstancesManagementPanel = new RemoteSailingServerInstancesManagementPanel(sailingService, this, getStringMessages());
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<RemoteSailingServerInstancesManagementPanel>(sailingServerInstancesManagementPanel),
getStringMessages().serverInstances(), Permission.MANAGE_SAILING_SERVER_INSTANCES);
RemoteServerInstancesManagementPanel remoteServerInstancesManagementPanel = new RemoteServerInstancesManagementPanel(sailingService, this, getStringMessages());
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<RemoteServerInstancesManagementPanel>(remoteServerInstancesManagementPanel),
getStringMessages().remoteServerInstances(), Permission.MANAGE_SAILING_SERVER_INSTANCES);
LocalServerManagementPanel localServerInstancesManagementPanel = new LocalServerManagementPanel(sailingService, this, getStringMessages());
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<LocalServerManagementPanel>(localServerInstancesManagementPanel),
getStringMessages().localServer(), Permission.MANAGE_LOCAL_SERVER_INSTANCE);
final DeviceConfigurationUserPanel deviceConfigurationUserPanel = new DeviceConfigurationUserPanel(sailingService,
getStringMessages(), this);
@@ -0,0 +1,138 @@
package com.sap.sailing.gwt.ui.adminconsole;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.ServerConfigurationDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.ServerInfoDTO;
public class LocalServerManagementPanel extends SimplePanel {
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
private final CaptionPanel serverInfoPanel;
private final CaptionPanel serverConfigurationPanel;
private CheckBox isStandaloneServerCheckbox;
private Label serverNameLabel;
private Label buildVersionLabel;
public LocalServerManagementPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
StringMessages stringMessages) {
this.sailingService = sailingService;
this.errorReporter = errorReporter;
this.stringMessages = stringMessages;
VerticalPanel mainPanel = new VerticalPanel();
setWidget(mainPanel);
mainPanel.setWidth("100%");
serverInfoPanel = new CaptionPanel("Server Information");
mainPanel.add(serverInfoPanel);
serverConfigurationPanel = new CaptionPanel("Server Configuration");
mainPanel.add(serverConfigurationPanel);
createServerInfoUI();
createServerConfigurationUI();
}
private void createServerInfoUI() {
VerticalPanel serverInfoContentPanel = new VerticalPanel();
serverInfoPanel.setContentWidget(serverInfoContentPanel);
serverNameLabel = new Label();
buildVersionLabel = new Label();
Grid grid = new Grid(2, 2);
grid.setWidget(0, 0, new Label(stringMessages.name() + ":"));
grid.setWidget(0, 1, serverNameLabel);
grid.setWidget(1, 0, new Label("Build version:"));
grid.setWidget(1, 1, buildVersionLabel);
serverInfoContentPanel.add(grid);
refreshServerInfo();
}
private void createServerConfigurationUI() {
VerticalPanel serverConfigurationContentPanel = new VerticalPanel();
serverConfigurationPanel.setContentWidget(serverConfigurationContentPanel);
isStandaloneServerCheckbox = new CheckBox();
isStandaloneServerCheckbox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
serverConfigurationChanged();
}
});
Grid grid = new Grid(2, 2);
grid.setWidget(0, 0, new Label("Standalone server:"));
grid.setWidget(0, 1, isStandaloneServerCheckbox);
serverConfigurationContentPanel.add(grid);
refreshServerConfiguration();
}
private void serverConfigurationChanged() {
ServerConfigurationDTO serverConfig = new ServerConfigurationDTO(isStandaloneServerCheckbox.getValue());
sailingService.updateServerConfiguration(serverConfig, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(caught.getMessage());
}
@Override
public void onSuccess(Void result) {
refreshServerConfiguration();
}
});
}
private void refreshServerInfo() {
sailingService.getServerInfo(new AsyncCallback<ServerInfoDTO>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(caught.getMessage());
}
@Override
public void onSuccess(ServerInfoDTO result) {
updateServerInfo(result);
}
});
}
private void refreshServerConfiguration() {
sailingService.getServerConfiguration(new AsyncCallback<ServerConfigurationDTO>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(caught.getMessage());
}
@Override
public void onSuccess(ServerConfigurationDTO result) {
updateServerConfiguration(result);
}
});
}
private void updateServerInfo(ServerInfoDTO result) {
serverNameLabel.setText(result.getServerName());
buildVersionLabel.setText(result.getBuildVersion() != null ? result.getBuildVersion() : "Unknown");
}
private void updateServerConfiguration(ServerConfigurationDTO result) {
isStandaloneServerCheckbox.setValue(result.isStandaloneServer(), true);
}
}
@@ -34,7 +34,7 @@ import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
public class RemoteSailingServerInstancesManagementPanel extends SimplePanel {
public class RemoteServerInstancesManagementPanel extends SimplePanel {
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
@@ -45,7 +45,7 @@ public class RemoteSailingServerInstancesManagementPanel extends SimplePanel {
private final CaptionPanel remoteServersPanel;
public RemoteSailingServerInstancesManagementPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
public RemoteServerInstancesManagementPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
StringMessages stringMessages) {
this.sailingService = sailingService;
this.errorReporter = errorReporter;
@@ -146,7 +146,7 @@ public class RemoteSailingServerInstancesManagementPanel extends SimplePanel {
builder.appendHtmlConstant("<br>");
}
} else {
builder.appendEscaped(RemoteSailingServerInstancesManagementPanel.this.stringMessages
builder.appendEscaped(RemoteServerInstancesManagementPanel.this.stringMessages
.errorAddingSailingServer(server.getLastErrorMessage()));
}
return builder.toSafeHtml();
@@ -76,6 +76,7 @@ import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO;
import com.sap.sailing.gwt.ui.shared.RemoteSailingServerReferenceDTO;
import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO;
import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO;
import com.sap.sailing.gwt.ui.shared.ServerConfigurationDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorResultsDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO;
@@ -95,6 +96,7 @@ import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.mail.MailException;
import com.sap.sse.common.search.KeywordQuery;
import com.sap.sse.gwt.client.ServerInfoDTO;
import com.sap.sse.gwt.client.filestorage.FileStorageManagementGwtService;
import com.sap.sse.gwt.client.media.ImageDTO;
import com.sap.sse.gwt.client.media.VideoDTO;
@@ -322,6 +324,12 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
WindInfoForRaceDTO getWindSourcesInfo(RegattaAndRaceIdentifier raceIdentifier);
ServerInfoDTO getServerInfo();
ServerConfigurationDTO getServerConfiguration();
void updateServerConfiguration(ServerConfigurationDTO serverConfiguration);
List<RemoteSailingServerReferenceDTO> getRemoteSailingServerReferences();
void removeSailingServers(Set<String> toRemove) throws Exception;
@@ -393,8 +401,6 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
boolean showOnlyCurrentlyRunningRaces, boolean showOnlyRacesOfSameDay, List<String> visibleRegattas)
throws Exception;
String getBuildVersion();
void stopReplicatingFromMaster();
void stopAllReplicas();
@@ -66,6 +66,7 @@ import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO;
import com.sap.sailing.gwt.ui.shared.RemoteSailingServerReferenceDTO;
import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO;
import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO;
import com.sap.sailing.gwt.ui.shared.ServerConfigurationDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorResultsDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO;
@@ -83,7 +84,7 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.search.KeywordQuery;
import com.sap.sse.gwt.client.BuildVersionRetriever;
import com.sap.sse.gwt.client.ServerInfoRetriever;
import com.sap.sse.gwt.client.filestorage.FileStorageManagementGwtServiceAsync;
import com.sap.sse.gwt.client.media.ImageDTO;
import com.sap.sse.gwt.client.media.VideoDTO;
@@ -91,7 +92,7 @@ import com.sap.sse.gwt.client.media.VideoDTO;
/**
* The async counterpart of {@link SailingService}
*/
public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageManagementGwtServiceAsync {
public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageManagementGwtServiceAsync {
void getRegattas(AsyncCallback<List<RegattaDTO>> callback);
@@ -424,6 +425,10 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
void updateRaceCourse(RegattaAndRaceIdentifier raceIdentifier, List<Util.Pair<ControlPointDTO, PassingInstruction>> controlPoints, AsyncCallback<Void> callback);
void getServerConfiguration(AsyncCallback<ServerConfigurationDTO> callback);
void updateServerConfiguration(ServerConfigurationDTO serverConfiguration, AsyncCallback<Void> callback);
void getRemoteSailingServerReferences(AsyncCallback<List<RemoteSailingServerReferenceDTO>> callback);
void removeSailingServers(Set<String> toRemove, AsyncCallback<Void> callback);
@@ -491,8 +496,6 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
void checkLeaderboardName(String leaderboardName, AsyncCallback<Util.Pair<String, LeaderboardType>> callback);
void getBuildVersion(AsyncCallback<String> callback);
void stopReplicatingFromMaster(AsyncCallback<Void> asyncCallback);
void getRegattaStructureForEvent(UUID eventId, AsyncCallback<List<RaceGroupDTO>> asyncCallback);
@@ -382,7 +382,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String pleaseEnterNonEmptyUrl();
String addResultImportUrl();
String errorAddingResultImportUrl(String message);
String serverInstances();
String remoteServerInstances();
String localServer();
String errorRefreshingSailingServers(String message);
String successfullyUpdatedSailingServers();
String errorRemovingSailingServers(String message);
@@ -392,7 +392,8 @@ errorRemovingResultImportUrls=Error removing result import URLs: {0}
pleaseEnterNonEmptyUrl=Please enter a URL.
addResultImportUrl=Add result import URL
errorAddingResultImportUrl=Error adding result import URL: {0}
serverInstances=Server Instances
remoteServerInstances=Remote Server Instances
localServer=Local Server
errorRefreshingSailingServers=Error refreshing SailingServer instances: {0}
successfullyUpdatedSailingServers=Successfully updated SailingServer instances
errorRemovingSailingServers=Error removing SailingServer instances: {0}
@@ -393,7 +393,8 @@ errorRemovingResultImportUrls=Fehler beim Löschen von Ergebnisimport URLs: {0}
pleaseEnterNonEmptyUrl=Bitte gebe eine URL ein.
addResultImportUrl=Ergebnisimport-URL hinzufügen
errorAddingResultImportUrl=Fehler beim Hinzufügen einer Ergebnisimport URL: {0}
serverInstances=Server Instanzen
remoteServerInstances=Remote-Server Instanzen
localServer=Lokaler Server
errorRefreshingSailingServers=Fehler beim Aktualisieren der SailingServer Instanzen: {0}
successfullyUpdatedSailingServers=SailingServer Instanzen erfolgreich aktualisiert
errorRemovingSailingServers=Fehler beim Löschen von SailingServer Instanzen: {0}
@@ -962,7 +962,8 @@ showDiagram=Show Diagram
rerunQueryAfterRefreshTooltip=Повторно запускает запрос после обновления таблиц.
queryDefinitionProvider=Поставщик определения запроса
statisticProvider=Поставщик статистических данных
serverInstances=Server Instances
remoteServerInstances=Remote Server Instances
localServer=Local Server
calculateThe=Calculate the
groupingProvider=Поставщик группировки
releaseNotes=Новости и история выпусков
@@ -111,7 +111,8 @@ leg=L
settingsForComponent=Settings for {0}
classFlag=Class flag
statisticProvider=Statistic Provider
serverInstances=Server Instances
remoteServerInstances=Remote Server Instances
localServer=Local Server
startRaceLogTracking=Start RaceLog Tracking
lastScoreCorrectionsComment=Last score correction comment
masterDataImportPanel=Master Data Import
@@ -111,6 +111,7 @@ import com.sap.sailing.domain.base.RaceColumnInSeries;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.base.SailingServerConfiguration;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence;
@@ -136,6 +137,7 @@ import com.sap.sailing.domain.base.impl.DynamicTeam;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SailingServerConfigurationImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.Bearing;
@@ -333,6 +335,7 @@ import com.sap.sailing.gwt.ui.shared.ReplicationMasterDTO;
import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO;
import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
import com.sap.sailing.gwt.ui.shared.ServerConfigurationDTO;
import com.sap.sailing.gwt.ui.shared.SidelineDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorResultsDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
@@ -407,6 +410,7 @@ import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCo
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCorrectionMetadata;
import com.sap.sailing.server.operationaltransformation.UpdateRaceDelayToLive;
import com.sap.sailing.server.operationaltransformation.UpdateSeries;
import com.sap.sailing.server.operationaltransformation.UpdateServerConfiguration;
import com.sap.sailing.server.operationaltransformation.UpdateSpecificRegatta;
import com.sap.sailing.server.simulation.SimulationService;
import com.sap.sailing.simulator.Path;
@@ -420,7 +424,7 @@ import com.sap.sailing.xrr.schema.RegattaResults;
import com.sap.sailing.xrr.structureimport.SeriesParameters;
import com.sap.sailing.xrr.structureimport.StructureImporter;
import com.sap.sailing.xrr.structureimport.buildstructure.SetRacenumberFromSeries;
import com.sap.sse.BuildVersion;
import com.sap.sse.ServerInfo;
import com.sap.sse.common.CountryCode;
import com.sap.sse.common.Duration;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
@@ -444,6 +448,7 @@ import com.sap.sse.common.search.KeywordQuery;
import com.sap.sse.common.search.Result;
import com.sap.sse.filestorage.FileStorageService;
import com.sap.sse.filestorage.InvalidPropertiesException;
import com.sap.sse.gwt.client.ServerInfoDTO;
import com.sap.sse.gwt.client.media.ImageDTO;
import com.sap.sse.gwt.client.media.VideoDTO;
import com.sap.sse.gwt.server.filestorage.FileStorageServiceDTOUtils;
@@ -3816,6 +3821,25 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
return result;
}
@Override
public ServerInfoDTO getServerInfo() {
ServerInfoDTO result = new ServerInfoDTO(ServerInfo.getName(), ServerInfo.getBuildVersion());
return result;
}
@Override
public ServerConfigurationDTO getServerConfiguration() {
SailingServerConfiguration sailingServerConfiguration = getService().getSailingServerConfiguration();
ServerConfigurationDTO result = new ServerConfigurationDTO(sailingServerConfiguration.isStandaloneServer());
return result;
}
@Override
public void updateServerConfiguration(ServerConfigurationDTO serverConfiguration) {
SailingServerConfiguration newServerConfiguration = new SailingServerConfigurationImpl(serverConfiguration.isStandaloneServer());
getService().apply(new UpdateServerConfiguration(newServerConfiguration));
}
@Override
public List<RemoteSailingServerReferenceDTO> getRemoteSailingServerReferences() {
List<RemoteSailingServerReferenceDTO> result = new ArrayList<RemoteSailingServerReferenceDTO>();
@@ -4233,11 +4257,6 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
return entry;
}
@Override
public String getBuildVersion() {
return BuildVersion.getBuildVersion();
}
@Override
public void stopReplicatingFromMaster() {
@@ -0,0 +1,19 @@
package com.sap.sailing.gwt.ui.shared;
import com.google.gwt.user.client.rpc.IsSerializable;
public class ServerConfigurationDTO implements IsSerializable {
private boolean isStandaloneServer;
// for GWT
ServerConfigurationDTO() {
}
public ServerConfigurationDTO(boolean isStandaloneServer) {
this.isStandaloneServer = isStandaloneServer;
}
public boolean isStandaloneServer() {
return isStandaloneServer;
}
}
@@ -32,6 +32,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaRegistry;
import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.base.SailingServerConfiguration;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationIdentifier;
@@ -584,6 +585,13 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
*/
Result<LeaderboardSearchResultBase> searchRemotely(String remoteServerReferenceName, KeywordQuery query);
/**
* Gets the configuration of the local sailing server instances.
*/
SailingServerConfiguration getSailingServerConfiguration();
void updateServerConfiguration(SailingServerConfiguration serverConfiguration);
/**
* 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."
@@ -77,6 +77,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaListener;
import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.base.SailingServerConfiguration;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.Waypoint;
@@ -209,7 +210,7 @@ import com.sap.sailing.server.operationaltransformation.UpdateWindAveragingTime;
import com.sap.sailing.server.operationaltransformation.UpdateWindSourcesToExclude;
import com.sap.sailing.server.simulation.SimulationService;
import com.sap.sailing.server.simulation.SimulationServiceFactory;
import com.sap.sse.BuildVersion;
import com.sap.sse.ServerInfo;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.TypeBasedServiceFinderFactory;
import com.sap.sse.common.Util;
@@ -398,6 +399,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
private final JoinedClassLoader joinedClassLoader;
private SailingServerConfiguration sailingServerConfiguration;
/**
* Providing the constructor parameters for a new {@link RacingEventServiceImpl} instance is a bit tricky
* in some cases because containment and initialization order of some types is fairly tightly coupled.
@@ -593,6 +596,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
this.configurationMap = new DeviceConfigurationMapImpl();
this.serviceFinderFactory = serviceFinderFactory;
sailingServerConfiguration = domainObjectFactory.loadServerConfiguration();
final Iterable<Pair<Event, Boolean>> loadedEventsWithRequireStoreFlag = loadStoredEvents();
loadStoredRegattas();
loadRaceIDToRegattaAssociations();
@@ -1135,6 +1139,17 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
return Collections.unmodifiableMap(new HashMap<String, Leaderboard>(leaderboardsByName));
}
@Override
public SailingServerConfiguration getSailingServerConfiguration() {
return sailingServerConfiguration;
}
@Override
public void updateServerConfiguration(SailingServerConfiguration serverConfiguration) {
this.sailingServerConfiguration = serverConfiguration;
mongoObjectFactory.storeServerConfiguration(serverConfiguration);
}
@Override
public Map<RemoteSailingServerReference, com.sap.sse.common.Util.Pair<Iterable<EventBase>, Exception>> getPublicEventsOfAllSailingServers() {
return remoteSailingServerSet.getCachedEventsForRemoteSailingServers(); // FIXME should probably add our own
@@ -2911,7 +2926,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
}
public String toString() {
return "RacingEventService: " + this.hashCode() + " Build: " + BuildVersion.getBuildVersion();
return "RacingEventService: " + this.hashCode() + " Build: " + ServerInfo.getBuildVersion();
}
@Override
@@ -0,0 +1,39 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.base.SailingServerConfiguration;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateServerConfiguration extends AbstractRacingEventServiceOperation<Void> {
private static final long serialVersionUID = -778186188996039972L;
private final SailingServerConfiguration serverConfiguration;
public UpdateServerConfiguration(SailingServerConfiguration serverConfiguration) {
super();
this.serverConfiguration = serverConfiguration;
}
/**
* {@link #internalApplyTo(RacingEventService)} already replicates the effects
*/
@Override
public boolean isRequiresExplicitTransitiveReplication() {
return false;
}
@Override
public Void internalApplyTo(RacingEventService toState) throws Exception {
toState.updateServerConfiguration(serverConfiguration);
return null;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
return null;
}
}
@@ -20,7 +20,7 @@ import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sse.common.Util.Triple;
import com.sap.sse.gwt.client.AbstractEntryPoint;
import com.sap.sse.gwt.client.BuildVersionRetriever;
import com.sap.sse.gwt.client.ServerInfoRetriever;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.panels.VerticalTabLayoutPanel;
import com.sap.sse.security.shared.Permission;
@@ -149,7 +149,7 @@ public class AdminConsolePanel extends DockLayoutPanel {
}
public AdminConsolePanel(UserService userService, PermissionsForRoleProvider permissionsForRoleProvider,
BuildVersionRetriever buildVersionRetriever, String releaseNotesAnchorLabel,
ServerInfoRetriever buildVersionRetriever, String releaseNotesAnchorLabel,
String releaseNotesURL, ErrorReporter errorReporter, LoginPanelCss loginPanelCss) {
super(Unit.EM);
this.permissionsForRoleProvider = permissionsForRoleProvider;
@@ -5,21 +5,22 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sse.gwt.client.BuildVersionRetriever;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.ServerInfoDTO;
import com.sap.sse.gwt.client.ServerInfoRetriever;
public class SystemInformationPanel extends FlowPanel {
private final Label buildVersionText;
public SystemInformationPanel(final BuildVersionRetriever buildVersionRetriever, final ErrorReporter errorReporter) {
public SystemInformationPanel(final ServerInfoRetriever buildVersionRetriever, final ErrorReporter errorReporter) {
super();
buildVersionText = new Label("");
addFloatingWidget(buildVersionText);
buildVersionRetriever.getBuildVersion(new AsyncCallback<String>() {
buildVersionRetriever.getServerInfo(new AsyncCallback<ServerInfoDTO>() {
@Override
public void onSuccess(String result) {
buildVersionText.setText("Version: " + result);
public void onSuccess(ServerInfoDTO result) {
buildVersionText.setText("Version: " + result.getBuildVersion());
}
@Override
@@ -1,7 +0,0 @@
package com.sap.sse.gwt.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface BuildVersionRetriever {
void getBuildVersion(AsyncCallback<String> callback);
}
@@ -0,0 +1,25 @@
package com.sap.sse.gwt.client;
import com.google.gwt.user.client.rpc.IsSerializable;
public class ServerInfoDTO implements IsSerializable {
private String serverName;
private String buildVersion;
// for GWT
ServerInfoDTO() {
}
public ServerInfoDTO(String serverName, String buildVersion) {
this.serverName = serverName;
this.buildVersion = buildVersion;
}
public String getBuildVersion() {
return buildVersion;
}
public String getServerName() {
return serverName;
}
}
@@ -0,0 +1,7 @@
package com.sap.sse.gwt.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface ServerInfoRetriever {
void getServerInfo(AsyncCallback<ServerInfoDTO> callback);
}
@@ -16,7 +16,7 @@ import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import com.sap.sse.BuildVersion;
import com.sap.sse.ServerInfo;
import com.sap.sse.replication.Replicable;
import com.sap.sse.replication.ReplicationMasterDescriptor;
@@ -79,7 +79,7 @@ public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescrip
return new URL("http", getHostname(), servletPort, REPLICATION_SERVLET + "?" + ReplicationServlet.ACTION + "="
+ ReplicationServlet.Action.REGISTER.name() + "&" + ReplicationServlet.SERVER_UUID + "="
+ uuid.toString() + "&" + ReplicationServlet.ADDITIONAL_INFORMATION + "="
+ java.net.URLEncoder.encode(BuildVersion.getBuildVersion(), "UTF-8"));
+ java.net.URLEncoder.encode(ServerInfo.getBuildVersion(), "UTF-8"));
}
@Override
@@ -32,7 +32,7 @@ import com.rabbitmq.client.AMQP.Queue.DeleteOk;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import com.sap.sse.BuildVersion;
import com.sap.sse.ServerInfo;
import com.sap.sse.common.Util;
import com.sap.sse.replication.OperationExecutionListener;
import com.sap.sse.replication.OperationWithResult;
@@ -631,7 +631,7 @@ public class ReplicationServiceImpl implements ReplicationService {
private String registerReplicaWithMaster(ReplicationMasterDescriptor master) throws IOException,
ClassNotFoundException {
URL replicationRegistrationRequestURL = master.getReplicationRegistrationRequestURL(getServerIdentifier(),
BuildVersion.getBuildVersion());
ServerInfo.getBuildVersion());
final URLConnection registrationRequestConnection = replicationRegistrationRequestURL.openConnection();
registrationRequestConnection.connect();
final InputStream content = (InputStream) registrationRequestConnection.getContent();
@@ -1,21 +0,0 @@
package com.sap.sse;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
public class BuildVersion {
public static String getBuildVersion() {
String version = "Unknown or Development (" + System.getProperty("com.sap.sailing.server.name") + ")";
File versionfile = new File(System.getProperty("jetty.home") + File.separator + "version.txt");
if (versionfile.exists()) {
try {
version = new BufferedReader(new FileReader(versionfile)).readLine();
} catch (Exception ex) {
/* ignore */
}
}
return version;
}
}
@@ -0,0 +1,29 @@
package com.sap.sse;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
/**
* A class providing static information about the running server.
* @author Frank
*
*/
public class ServerInfo {
public static String getBuildVersion() {
String version = "Unknown or Development (" + ServerStartupConstants.SERVER_NAME + ")";
File versionfile = new File(ServerStartupConstants.JETTY_HOME + File.separator + "version.txt");
if (versionfile.exists()) {
try {
version = new BufferedReader(new FileReader(versionfile)).readLine();
} catch (Exception ex) {
/* ignore */
}
}
return version;
}
public static String getName() {
return ServerStartupConstants.SERVER_NAME;
}
}
@@ -0,0 +1,6 @@
package com.sap.sse;
public interface ServerStartupConstants {
final static String SERVER_NAME = System.getProperty("com.sap.sailing.server.name");
final static String JETTY_HOME = System.getProperty("jetty.home");
}