Merge branch 'master' into dataMining
Conflicts: java/com.sap.sailing.gwt.ui/SailingGWT.launch java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
No files matched your search
@@ -12,8 +12,8 @@ find_project_home ()
|
||||
PARENT_DIR=`cd $1/..;pwd`
|
||||
OUTPUT=$(find_project_home $PARENT_DIR)
|
||||
|
||||
if [ "$OUTPUT" = "" ] && [ -d "$PARENT_DIR/code" ] && [ -d "$PARENT_DIR/code/.git" ]; then
|
||||
OUTPUT="$PARENT_DIR/code"
|
||||
if [ "$OUTPUT" = "" ] && [ -d "$PARENT_DIR/$CODE_DIRECTORY" ] && [ -d "$PARENT_DIR/$CODE_DIRECTORY/.git" ]; then
|
||||
OUTPUT="$PARENT_DIR/$CODE_DIRECTORY"
|
||||
fi
|
||||
echo $OUTPUT
|
||||
return 0
|
||||
@@ -329,8 +329,12 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
|
||||
extra="$extra -P no-debug.without-proxy"
|
||||
fi
|
||||
|
||||
echo "Using following command: mvn $extra -fae -s $MAVEN_SETTINGS $clean install"
|
||||
mvn $extra -fae -s $MAVEN_SETTINGS $clean install 2>&1 | tee $START_DIR/build.log
|
||||
# make sure to honour the service configuration
|
||||
# needed to make sure that tests use the right servers
|
||||
APP_PARAMETERS="-Dmongo.host=$MONGODB_HOST -Dmongo.port=$MONGODB_PORT -Dexpedition.udp.port=$EXPEDITION_PORT -Dreplication.exchangeHost=$REPLICATION_HOST -Dreplication.exchangeName=$REPLICATION_CHANNEL"
|
||||
|
||||
echo "Using following command: mvn $extra -DargLine=\"$APP_PARAMETERS\" -fae -s $MAVEN_SETTINGS $clean install"
|
||||
mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean install 2>&1 | tee $START_DIR/build.log
|
||||
|
||||
if [ $gwtcompile -eq 1 ]; then
|
||||
# Now move back the backup .gwt.xml files before they were (maybe) patched
|
||||
@@ -393,6 +397,7 @@ if [[ "$@" == "install" ]] || [[ "$@" == "all" ]]; then
|
||||
cp -v $PROJECT_HOME/java/target/start $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/stop $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/status $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/shouldIBuildOrShouldIGo.sh $ACDIR/
|
||||
|
||||
if [ ! -f "$ACDIR/env.sh" ]; then
|
||||
cp -v $PROJECT_HOME/java/target/env.sh $ACDIR/
|
||||
|
||||
@@ -166,62 +166,10 @@ public class DeclinationStore {
|
||||
Calendar cal = new GregorianCalendar(year, month, /* dayOfMonth */ 1);
|
||||
TimePoint timePoint = new MillisecondsTimePoint(cal.getTimeInMillis());
|
||||
for (double lat = 0; lat < 90; lat += grid) {
|
||||
System.out.println("Date: " + year + "/" + (month + 1) + ", Latitude: " + lat);
|
||||
for (double lng = 0; lng < 180; lng += grid) {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (existingDeclinationRecord == null
|
||||
|| DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord
|
||||
.getPosition().getDistance(point), timePoint, existingDeclinationRecord
|
||||
.getTimePoint()) > 0.1) {
|
||||
// less than ~6 nautical miles and/or ~.6 months off
|
||||
fetchAndAppendDeclination(timePoint, point, importer, out);
|
||||
}
|
||||
}
|
||||
for (double lng = -grid; lng > -180; lng -= grid) {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (existingDeclinationRecord == null
|
||||
|| DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord
|
||||
.getPosition().getDistance(point), timePoint, existingDeclinationRecord
|
||||
.getTimePoint()) > 0.1) {
|
||||
// less than ~6 nautical miles and/or ~.6 months off
|
||||
fetchAndAppendDeclination(timePoint, point, importer, out);
|
||||
}
|
||||
}
|
||||
fetchAndAppendDeclinationForLatitude(grid, importer, year, storedDeclinations, out, month, timePoint, lat);
|
||||
}
|
||||
for (double lat = -grid; lat > -90; lat -= grid) {
|
||||
System.out.println("Date: " + year + "/" + (month + 1) + ", Latitude: " + lat);
|
||||
for (double lng = 0; lng < 180; lng += grid) {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord.getPosition().getDistance(point),
|
||||
timePoint, existingDeclinationRecord.getTimePoint()) > 0.1) {
|
||||
// less than ~6 nautical miles and/or ~.6 months off
|
||||
fetchAndAppendDeclination(timePoint, point, importer, out);
|
||||
}
|
||||
}
|
||||
for (double lng = -grid; lng > -180; lng -= grid) {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord.getPosition().getDistance(point),
|
||||
timePoint, existingDeclinationRecord.getTimePoint()) > 0.1) {
|
||||
// less than ~6 nautical miles and/or ~.6 months off
|
||||
fetchAndAppendDeclination(timePoint, point, importer, out);
|
||||
}
|
||||
}
|
||||
fetchAndAppendDeclinationForLatitude(grid, importer, year, storedDeclinations, out, month, timePoint, lat);
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
@@ -229,6 +177,33 @@ public class DeclinationStore {
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchAndAppendDeclinationForLatitude(double grid, NOAAImporter importer, int year,
|
||||
QuadTree<Declination> storedDeclinations, Writer out, int month, TimePoint timePoint, double lat)
|
||||
throws IOException {
|
||||
System.out.println("Date: " + year + "/" + (month + 1) + ", Latitude: " + lat);
|
||||
for (double lng = 0; lng < 180; lng += grid) {
|
||||
fetchAndAppendDeclination(importer, storedDeclinations, out, timePoint, lat, lng);
|
||||
}
|
||||
for (double lng = -grid; lng > -180; lng -= grid) {
|
||||
fetchAndAppendDeclination(importer, storedDeclinations, out, timePoint, lat, lng);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchAndAppendDeclination(NOAAImporter importer, QuadTree<Declination> storedDeclinations, Writer out,
|
||||
TimePoint timePoint, double lat, double lng) throws IOException {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
final Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (existingDeclinationRecord == null
|
||||
|| DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord.getPosition().getDistance(point),
|
||||
timePoint, existingDeclinationRecord.getTimePoint()) > 0.1) {
|
||||
// less than ~6 nautical miles and/or ~.6 months off
|
||||
fetchAndAppendDeclination(timePoint, point, importer, out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches the importer, writing to resources/declination-year.txt (where "year" represents the year for which the
|
||||
* values are stored in the file) the declinations downloaded online for the years <code>args[0]</code> to
|
||||
|
||||
@@ -476,7 +476,8 @@ public class ClientParamsPHP {
|
||||
}
|
||||
|
||||
public Race getRace() {
|
||||
return new Race(UUID.fromString(properties.get("RaceID")));
|
||||
final String raceId = properties.get("RaceID");
|
||||
return raceId == null ? null : new Race(UUID.fromString(raceId));
|
||||
}
|
||||
|
||||
public Event getEvent() {
|
||||
|
||||
@@ -284,41 +284,47 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
||||
final ClientParamsPHP clientParams;
|
||||
try {
|
||||
clientParams = new ClientParamsPHP(paramURL, new InputStreamReader(paramURL.openStream()));
|
||||
List<Pair<com.sap.sailing.domain.base.ControlPoint, NauticalSide>> newCourseControlPointsWithPassingSide = getControlPointsWithPassingSide(clientParams,
|
||||
new ControlPointProducer<com.sap.sailing.domain.base.ControlPoint>() {
|
||||
@Override
|
||||
public com.sap.sailing.domain.base.ControlPoint produceControlPoint(TracTracControlPoint ttControlPoint) {
|
||||
return domainFactory.getOrCreateControlPoint(ttControlPoint);
|
||||
}
|
||||
});
|
||||
if (getRaces() == null || getRaces().isEmpty()) {
|
||||
// create race definition / tracked race and add to event
|
||||
final String raceName = clientParams.getRace().getName();
|
||||
logger.log(Level.INFO, "Found data for non-existing race "+raceName+" in "+paramURL+". Creating RaceDefinition.");
|
||||
final Iterable<Competitor> competitors = getCompetitors(clientParams);
|
||||
final Iterable<com.sap.sailing.domain.tractracadapter.impl.ClientParamsPHP.Competitor> competitorsInClientParams = clientParams.getCompetitors();
|
||||
List<Pair<TracTracControlPoint, NauticalSide>> ttControlPointsAndPassingSide = getControlPointsWithPassingSide(clientParams,
|
||||
new ControlPointProducer<TracTracControlPoint>() {
|
||||
@Override
|
||||
public TracTracControlPoint produceControlPoint(TracTracControlPoint ttControlPoint) {
|
||||
return ttControlPoint;
|
||||
if (clientParams.getRace() != null) {
|
||||
List<Pair<com.sap.sailing.domain.base.ControlPoint, NauticalSide>> newCourseControlPointsWithPassingSide = getControlPointsWithPassingSide(
|
||||
clientParams, new ControlPointProducer<com.sap.sailing.domain.base.ControlPoint>() {
|
||||
@Override
|
||||
public com.sap.sailing.domain.base.ControlPoint produceControlPoint(
|
||||
TracTracControlPoint ttControlPoint) {
|
||||
return domainFactory.getOrCreateControlPoint(ttControlPoint);
|
||||
}
|
||||
});
|
||||
if (getRaces() == null || getRaces().isEmpty()) {
|
||||
// create race definition / tracked race and add to event
|
||||
final String raceName = clientParams.getRace().getName();
|
||||
logger.log(Level.INFO, "Found data for non-existing race " + raceName + " in " + paramURL
|
||||
+ ". Creating RaceDefinition.");
|
||||
final Iterable<Competitor> competitors = getCompetitors(clientParams);
|
||||
final Iterable<com.sap.sailing.domain.tractracadapter.impl.ClientParamsPHP.Competitor> competitorsInClientParams = clientParams
|
||||
.getCompetitors();
|
||||
List<Pair<TracTracControlPoint, NauticalSide>> ttControlPointsAndPassingSide = getControlPointsWithPassingSide(
|
||||
clientParams, new ControlPointProducer<TracTracControlPoint>() {
|
||||
@Override
|
||||
public TracTracControlPoint produceControlPoint(TracTracControlPoint ttControlPoint) {
|
||||
return ttControlPoint;
|
||||
}
|
||||
});
|
||||
Course course = domainFactory.createCourse(clientParams.getRace().getDefaultRoute()
|
||||
.getDescription(), ttControlPointsAndPassingSide);
|
||||
List<Sideline> sidelines = domainFactory.createSidelines(clientParams.getRace().getMetadata(),
|
||||
clientParams.getEvent().getControlPointList());
|
||||
DynamicTrackedRace trackedRace = domainFactory.getOrCreateRaceDefinitionAndTrackedRace(
|
||||
getTrackedRegatta(), clientParams.getRace().getId(), raceName, competitors,
|
||||
getDominantBoatClass(competitorsInClientParams), course, sidelines, windStore,
|
||||
delayToLiveInMillis, WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND, /* raceDefinitionSetToUpdate */
|
||||
this, tracTracUpdateURI, tractracEvent.getId(), tracTracUsername, tracTracPassword);
|
||||
if (simulator != null) {
|
||||
simulator.setTrackedRace(trackedRace);
|
||||
}
|
||||
});
|
||||
Course course = domainFactory.createCourse(clientParams.getRace().getDefaultRoute().getDescription(), ttControlPointsAndPassingSide);
|
||||
List<Sideline> sidelines = domainFactory.createSidelines(
|
||||
clientParams.getRace().getMetadata(), clientParams.getEvent().getControlPointList());
|
||||
DynamicTrackedRace trackedRace = domainFactory.getOrCreateRaceDefinitionAndTrackedRace(
|
||||
getTrackedRegatta(), clientParams.getRace().getId(), raceName, competitors,
|
||||
getDominantBoatClass(competitorsInClientParams), course, sidelines, windStore, delayToLiveInMillis,
|
||||
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND, /* raceDefinitionSetToUpdate */ this, tracTracUpdateURI,
|
||||
tractracEvent.getId(), tracTracUsername, tracTracPassword);
|
||||
if (simulator != null) {
|
||||
simulator.setTrackedRace(trackedRace);
|
||||
}
|
||||
compareAndUpdateCourseIfNecessary(newCourseControlPointsWithPassingSide);
|
||||
updateStartStopTimesAndLiveDelay(clientParams, simulator);
|
||||
updateMarkPositionsIfNoPositionsReceivedYet(clientParams);
|
||||
}
|
||||
compareAndUpdateCourseIfNecessary(newCourseControlPointsWithPassingSide);
|
||||
updateStartStopTimesAndLiveDelay(clientParams, simulator);
|
||||
updateMarkPositionsIfNoPositionsReceivedYet(clientParams);
|
||||
} catch (Exception e) {
|
||||
logger.info("Exception " + e.getMessage() + " while trying to read clientparams.php for races " + getRaces());
|
||||
logger.log(Level.SEVERE, "scheduleClientParamsPHPPoller.run", e);
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
|
||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/AdminConsole.html"/>
|
||||
|
||||
@@ -14,7 +14,6 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialog;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialog.DialogCallback;
|
||||
@@ -146,9 +145,9 @@ public class ReplicationPanel extends FlowPanel {
|
||||
|
||||
private void addReplication() {
|
||||
AddReplicationDialog dialog = new AddReplicationDialog(null,
|
||||
new DialogCallback<Triple<Pair<String, String>, Integer, Integer>>() {
|
||||
new DialogCallback<Triple<Triple<String, String, String>, Integer, Integer>>() {
|
||||
@Override
|
||||
public void ok(final Triple<Pair<String, String>, Integer, Integer> masterNameAndExchangeNameAndMessagingPortNumberAndServletPortNumber) {
|
||||
public void ok(final Triple<Triple<String, String, String>, Integer, Integer> masterNameAndExchangeNameAndMessagingPortNumberAndServletPortNumber) {
|
||||
registeredMasters.removeRow(0);
|
||||
registeredMasters.insertRow(0);
|
||||
registeredMasters.setWidget(0, 0, new Label(stringMessages.loading()));
|
||||
@@ -156,6 +155,7 @@ public class ReplicationPanel extends FlowPanel {
|
||||
stopReplicationButton.setEnabled(false);
|
||||
sailingService.startReplicatingFromMaster(masterNameAndExchangeNameAndMessagingPortNumberAndServletPortNumber.getA().getA(),
|
||||
masterNameAndExchangeNameAndMessagingPortNumberAndServletPortNumber.getA().getB(),
|
||||
masterNameAndExchangeNameAndMessagingPortNumberAndServletPortNumber.getA().getC(),
|
||||
masterNameAndExchangeNameAndMessagingPortNumberAndServletPortNumber.getC(),
|
||||
masterNameAndExchangeNameAndMessagingPortNumberAndServletPortNumber.getB(), new AsyncCallback<Void>() {
|
||||
@Override
|
||||
@@ -275,17 +275,19 @@ public class ReplicationPanel extends FlowPanel {
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
private class AddReplicationDialog extends DataEntryDialog<Triple<Pair<String, String>, Integer, Integer>> {
|
||||
private class AddReplicationDialog extends DataEntryDialog<Triple<Triple<String, String, String>, Integer, Integer>> {
|
||||
private final TextBox hostnameEntryField;
|
||||
private final TextBox exchangeHostnameEntryField;
|
||||
private final TextBox exchangenameEntryField;
|
||||
private final IntegerBox messagingPortField;
|
||||
private final IntegerBox servletPortField;
|
||||
|
||||
public AddReplicationDialog(final Validator<Triple<Pair<String, String>, Integer, Integer>> validator,
|
||||
final DialogCallback<Triple<Pair<String, String>, Integer, Integer>> callback) {
|
||||
public AddReplicationDialog(final Validator<Triple<Triple<String, String, String>, Integer, Integer>> validator,
|
||||
final DialogCallback<Triple<Triple<String, String, String>, Integer, Integer>> callback) {
|
||||
super(stringMessages.connect(), stringMessages.enterMaster(),
|
||||
stringMessages.ok(), stringMessages.cancel(), validator, callback);
|
||||
hostnameEntryField = createTextBox("localhost");
|
||||
exchangeHostnameEntryField = createTextBox("localhost");
|
||||
exchangenameEntryField = createTextBox("sapsailinganalytics");
|
||||
messagingPortField = createIntegerBox(0, /* visible length */ 5);
|
||||
servletPortField = createIntegerBox(8888, /* visibleLength */ 5);
|
||||
@@ -297,19 +299,26 @@ public class ReplicationPanel extends FlowPanel {
|
||||
*/
|
||||
@Override
|
||||
protected Widget getAdditionalWidget() {
|
||||
Grid grid = new Grid(8, 2);
|
||||
Grid grid = new Grid(10, 2);
|
||||
grid.setWidget(0, 0, new Label(stringMessages.hostname()));
|
||||
grid.setWidget(0, 1, hostnameEntryField);
|
||||
grid.setWidget(1, 0, new Label(stringMessages.explainReplicationHostname()));
|
||||
grid.setWidget(2, 0, new Label(stringMessages.exchangeName()));
|
||||
grid.setWidget(2, 1, exchangenameEntryField);
|
||||
grid.setWidget(3, 0, new Label(stringMessages.explainReplicationExchangeName()));
|
||||
grid.setWidget(4, 0, new Label(stringMessages.messagingPortNumber()));
|
||||
grid.setWidget(4, 1, messagingPortField);
|
||||
grid.setWidget(5, 0, new Label(stringMessages.explainReplicationExchangePort()));
|
||||
grid.setWidget(6, 0, new Label(stringMessages.servletPortNumber()));
|
||||
grid.setWidget(6, 1, servletPortField);
|
||||
grid.setWidget(7, 0, new Label(stringMessages.explainReplicationServletPort()));
|
||||
|
||||
grid.setWidget(2, 0, new Label(stringMessages.exchangeHost()));
|
||||
grid.setWidget(2, 1, exchangeHostnameEntryField);
|
||||
grid.setWidget(3, 0, new Label(stringMessages.explainExchangeHostName()));
|
||||
|
||||
grid.setWidget(4, 0, new Label(stringMessages.exchangeName()));
|
||||
grid.setWidget(4, 1, exchangenameEntryField);
|
||||
grid.setWidget(5, 0, new Label(stringMessages.explainReplicationExchangeName()));
|
||||
|
||||
grid.setWidget(6, 0, new Label(stringMessages.messagingPortNumber()));
|
||||
grid.setWidget(6, 1, messagingPortField);
|
||||
grid.setWidget(7, 0, new Label(stringMessages.explainReplicationExchangePort()));
|
||||
|
||||
grid.setWidget(8, 0, new Label(stringMessages.servletPortNumber()));
|
||||
grid.setWidget(8, 1, servletPortField);
|
||||
grid.setWidget(9, 0, new Label(stringMessages.explainReplicationServletPort()));
|
||||
return grid;
|
||||
}
|
||||
|
||||
@@ -320,9 +329,9 @@ public class ReplicationPanel extends FlowPanel {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Triple<Pair<String, String>, Integer, Integer> getResult() {
|
||||
return new Triple<Pair<String, String>, Integer, Integer>(
|
||||
new Pair<String, String>(hostnameEntryField.getText(), exchangenameEntryField.getText()),
|
||||
protected Triple<Triple<String, String, String>, Integer, Integer> getResult() {
|
||||
return new Triple<Triple<String, String, String>, Integer, Integer>(
|
||||
new Triple<String, String, String>(exchangeHostnameEntryField.getText(), hostnameEntryField.getText(), exchangenameEntryField.getText()),
|
||||
messagingPortField.getValue(), servletPortField.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ public interface SailingService extends RemoteService {
|
||||
|
||||
ReplicationStateDTO getReplicaInfo();
|
||||
|
||||
void startReplicatingFromMaster(String masterName, String exchangeName, int servletPort, int messagingPort) throws Exception;
|
||||
void startReplicatingFromMaster(String messagingHost, String masterHost, String exchangeName, int servletPort, int messagingPort) throws Exception;
|
||||
|
||||
void updateRaceDelayToLive(RegattaAndRaceIdentifier regattaAndRaceIdentifier, long delayToLiveInMs);
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ public interface SailingServiceAsync {
|
||||
|
||||
void getReplicaInfo(AsyncCallback<ReplicationStateDTO> callback);
|
||||
|
||||
void startReplicatingFromMaster(String masterName, String exchangeName, int servletPort, int messagingPort,
|
||||
void startReplicatingFromMaster(String messagingHost, String masterName, String exchangeName, int servletPort, int messagingPort,
|
||||
AsyncCallback<Void> callback);
|
||||
|
||||
void getEvents(AsyncCallback<List<EventDTO>> callback);
|
||||
|
||||
@@ -845,5 +845,7 @@ public interface StringMessages extends Messages {
|
||||
String raceTimeUpwindTooltip();
|
||||
String queryNotValidBecause();
|
||||
String dataMining();
|
||||
String exchangeHost();
|
||||
String explainExchangeHostName();
|
||||
String errorRunningDataMiningQuery();
|
||||
}
|
||||
@@ -684,7 +684,9 @@ firstRaceIsNonDiscardableCarryForward=Starts with non-discardable carry-forward
|
||||
addReplicationMaster=Connect to replication master server
|
||||
connect=Connect
|
||||
connectToMaster=Connect to Master
|
||||
explainReplicationHostname=Hostname where the replication master is running on. This is also the host where the messaging queue is running on.
|
||||
exchangeHost=Messaging Hostname
|
||||
explainExchangeHostName=Hostname where the messaging queue is running on.
|
||||
explainReplicationHostname=Hostname where the replication master is running on.
|
||||
explainReplicationExchangeName=The name of the exchange queue. It must be the same as configured in master.
|
||||
explainReplicationExchangePort=The port of the messaging exchange queue. This is used for all data after initial load.
|
||||
explainReplicationServletPort=Servlet port number that is used to connect to register this replica and receive initial load.
|
||||
@@ -838,4 +840,4 @@ noDimensionToGroupBySelectedError=No dimension to group by is selected
|
||||
noGrouperSelectedError=No grouper type is selected
|
||||
queryNotValidBecause=No query possible, because
|
||||
dataMining=Data Mining
|
||||
errorRunningDataMiningQuery=An error occured running the query
|
||||
errorRunningDataMiningQuery=An error occured running the query
|
||||
@@ -681,9 +681,11 @@ importSuccess=Erfolg\nEs wurden {0} leaderboard group(s) und {1} leaderboard(s)
|
||||
addReplicationMaster=Verbindung mit Master herstellen
|
||||
connect=Verbinden
|
||||
connectToMaster=Mit einem Master verbinden
|
||||
explainReplicationHostname=Der Name oder die IP des Servers auf dem der Master und die Queue laufen.
|
||||
exchangeHost=Queue Server
|
||||
explainExchangeHostName=Name oder IP des Servers auf dem die Queue läuft.
|
||||
explainReplicationHostname=Der Name oder die IP des Servers auf dem der Master Java Server läuft.
|
||||
explainReplicationExchangeName=Name der Messaging Queue.
|
||||
explainReplicationExchangePort=Port der Messaging Queue.
|
||||
explainReplicationExchangePort=Port des Messaging Queue Servers.
|
||||
explainReplicationServletPort=Servlet Port.
|
||||
explainReplicasRegistered=Registrierte Replicas (dieser Server ist der Master):
|
||||
explainConnectionsToMaster=Verbindungen zu einem Master (dieser Server ist eine Replica)
|
||||
@@ -834,4 +836,4 @@ noDimensionToGroupBySelectedError=Keine Gruppierungs-Dimension ausgewählt ist
|
||||
noGrouperSelectedError=Kein Gruppierungs-Typ ausgewählt ist
|
||||
queryNotValidBecause=Keine Datenabfrage möglich, da
|
||||
dataMining=Data Mining
|
||||
errorRunningDataMiningQuery=Es ist ein Felher bei der Datenabfrage aufgetreten
|
||||
errorRunningDataMiningQuery=Es ist ein Felher bei der Datenabfrage aufgetreten
|
||||
@@ -2534,11 +2534,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startReplicatingFromMaster(String masterName, String exchangeName, int servletPort, int messagingPort) throws IOException, ClassNotFoundException, InterruptedException {
|
||||
public void startReplicatingFromMaster(String messagingHost, String masterHost, String exchangeName, int servletPort, int messagingPort) throws IOException, ClassNotFoundException, InterruptedException {
|
||||
// the queue name must be always the same for this server. in order to achieve
|
||||
// this we're using the unique server identifier
|
||||
getReplicationService().startToReplicateFrom(
|
||||
ReplicationFactory.INSTANCE.createReplicationMasterDescriptor(masterName, exchangeName, servletPort, messagingPort,
|
||||
ReplicationFactory.INSTANCE.createReplicationMasterDescriptor(messagingHost, masterHost, exchangeName, servletPort, messagingPort,
|
||||
getReplicationService().getServerIdentifier().toString()));
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@ public class CourseAreaDescriptor {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public double getRadiusInMeters() {
|
||||
return (radius*1852.0);
|
||||
}
|
||||
|
||||
public LatLng getCenterPos() {
|
||||
return centerPos;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.sap.sailing.gwt.ui.simulator;
|
||||
|
||||
import com.google.gwt.maps.client.MapWidget;
|
||||
import com.google.gwt.maps.client.base.Point;
|
||||
import com.google.gwt.maps.client.events.center.CenterChangeMapEvent;
|
||||
import com.google.gwt.maps.client.events.center.CenterChangeMapHandler;
|
||||
import com.google.gwt.resources.client.ImageResource;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.ImageTransformer;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.CanvasOverlayV3;
|
||||
|
||||
public class ImageCanvasOverlay extends CanvasOverlayV3 {
|
||||
|
||||
private int canvasWidth;
|
||||
private int canvasHeight;
|
||||
|
||||
private int oLeft;
|
||||
private int oTop;
|
||||
|
||||
private double bearing = 0.0;
|
||||
|
||||
private ImageTransformer imgTrafo;
|
||||
|
||||
public ImageCanvasOverlay(MapWidget map, int zIndex, ImageResource img) {
|
||||
|
||||
super(map, zIndex);
|
||||
canvasWidth = 100;
|
||||
canvasHeight = 100;
|
||||
|
||||
if(getCanvas() != null) {
|
||||
//setCanvasPosition(map.getAbsoluteLeft(), map.getAbsoluteTop());
|
||||
getCanvas().setWidth(String.valueOf(canvasWidth));
|
||||
getCanvas().setHeight(String.valueOf(canvasHeight));
|
||||
getCanvas().setCoordinateSpaceWidth(canvasWidth);
|
||||
getCanvas().setCoordinateSpaceHeight(canvasHeight);
|
||||
}
|
||||
|
||||
imgTrafo = new ImageTransformer(img);
|
||||
|
||||
|
||||
getMap().addCenterChangeHandler(new CenterChangeMapHandler() {
|
||||
@Override
|
||||
public void onEvent(CenterChangeMapEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
setPosition();
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void addToMap() {
|
||||
super.addToMap();
|
||||
}
|
||||
|
||||
|
||||
public void setPosition() {
|
||||
|
||||
if (mapProjection != null) {
|
||||
Point sw = mapProjection.fromLatLngToDivPixel(getMap().getBounds().getSouthWest());
|
||||
Point ne = mapProjection.fromLatLngToDivPixel(getMap().getBounds().getNorthEast());
|
||||
double pLeft = Math.min(sw.getX(), ne.getX()) - 25 + oLeft;
|
||||
double pTop = Math.min(sw.getY(), ne.getY()) - 25 + oTop;
|
||||
setCanvasPosition(pLeft, pTop);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setOffset(int offsetLeft, int offsetTop) {
|
||||
this.oLeft = offsetLeft;
|
||||
this.oTop = offsetTop;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void draw() {
|
||||
|
||||
if(mapProjection != null) {
|
||||
|
||||
setPosition();
|
||||
imgTrafo.drawToCanvas(getCanvas(), bearing, 1.0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void setBearing(double bearing) {
|
||||
this.bearing = bearing;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import com.google.gwt.maps.client.geometrylib.SphericalUtils;
|
||||
import com.google.gwt.maps.client.overlays.Marker;
|
||||
import com.sap.sailing.domain.common.Mile;
|
||||
import com.sap.sailing.gwt.ui.simulator.racemap.FullCanvasOverlay;
|
||||
import com.sap.sailing.simulator.util.SailingSimulatorConstants;
|
||||
|
||||
/**
|
||||
* This class implements the layer to display the race course on the map. Currently the course only consists of the
|
||||
@@ -30,6 +31,7 @@ public class RaceCourseCanvasOverlay extends FullCanvasOverlay {
|
||||
|
||||
private String racecourseColor = "White";
|
||||
private double racecourseBuoySize = 5;
|
||||
private char mode;
|
||||
|
||||
// TODO: make private!!!
|
||||
public char raceCourseDirection;
|
||||
@@ -55,9 +57,10 @@ public class RaceCourseCanvasOverlay extends FullCanvasOverlay {
|
||||
}
|
||||
}
|
||||
|
||||
public RaceCourseCanvasOverlay(MapWidget map, int zIndex) {
|
||||
public RaceCourseCanvasOverlay(MapWidget map, int zIndex, char mode) {
|
||||
super(map, zIndex);
|
||||
|
||||
this.mode = mode;
|
||||
startPoint = null;
|
||||
endPoint = null;
|
||||
startMarker = null;
|
||||
@@ -65,37 +68,41 @@ public class RaceCourseCanvasOverlay extends FullCanvasOverlay {
|
||||
|
||||
getCanvas().getElement().setClassName("raceCourse");
|
||||
|
||||
map.addClickHandler(new ClickMapHandler() {
|
||||
@Override
|
||||
public void onEvent(ClickMapEvent event) {
|
||||
if (startPoint == null) {
|
||||
startPoint = event.getMouseEvent().getLatLng();
|
||||
logger.fine("Clicked startPoint here " + startPoint);
|
||||
if (startPoint != null) {
|
||||
if (this.mode == SailingSimulatorConstants.ModeFreestyle) {
|
||||
|
||||
setCanvasSettings();
|
||||
// drawCanvas();
|
||||
setStartPoint(startPoint);
|
||||
registeredRaceCourseMouseMoveHandler = getMap().addMouseMoveHandler(new RaceCourseMapMouseMoveHandler());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
map.addClickHandler(new ClickMapHandler() {
|
||||
@Override
|
||||
public void onEvent(ClickMapEvent event) {
|
||||
if (startPoint == null) {
|
||||
startPoint = event.getMouseEvent().getLatLng();
|
||||
logger.fine("Clicked startPoint here " + startPoint);
|
||||
if (startPoint != null) {
|
||||
|
||||
setCanvasSettings();
|
||||
// drawCanvas();
|
||||
setStartPoint(startPoint);
|
||||
registeredRaceCourseMouseMoveHandler = getMap().addMouseMoveHandler(new RaceCourseMapMouseMoveHandler());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
map.addDblClickHandler(new DblClickMapHandler() {
|
||||
@Override
|
||||
public void onEvent(DblClickMapEvent event) {
|
||||
if (isSelected) {
|
||||
endPoint = event.getMouseEvent().getLatLng();
|
||||
logger.info("Clicked endPoint " + "here " + endPoint);
|
||||
if (endPoint != null) {
|
||||
setEndPoint(endPoint);
|
||||
center();
|
||||
registeredRaceCourseMouseMoveHandler.removeHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
map.addDblClickHandler(new DblClickMapHandler() {
|
||||
@Override
|
||||
public void onEvent(DblClickMapEvent event) {
|
||||
if (isSelected) {
|
||||
endPoint = event.getMouseEvent().getLatLng();
|
||||
logger.info("Clicked endPoint " + "here " + endPoint);
|
||||
if (endPoint != null) {
|
||||
setEndPoint(endPoint);
|
||||
center();
|
||||
registeredRaceCourseMouseMoveHandler.removeHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
@@ -121,66 +128,15 @@ public class RaceCourseCanvasOverlay extends FullCanvasOverlay {
|
||||
int zoomLevel = map.getZoom();
|
||||
racecourseBuoySize = 1.0 + (5.0 - 1.0)*(zoomLevel - 10.0)/(14.0 - 10.0);
|
||||
setStartPoint(startPoint);
|
||||
setEndPoint(endPoint);
|
||||
setEndPoint(endPoint);
|
||||
}
|
||||
|
||||
private void setStartPoint(LatLng startPoint) {
|
||||
this.startPoint = startPoint;
|
||||
|
||||
if (startPoint != null) {
|
||||
Point point = mapProjection.fromLatLngToDivPixel(startPoint);
|
||||
drawCircleWithText(point.getX() - getWidgetPosLeft(), point.getY() - getWidgetPosTop(), racecourseBuoySize,
|
||||
racecourseColor, "Start");
|
||||
if (startMarker != null) {
|
||||
startMarker.setPosition(startPoint);
|
||||
} else {
|
||||
// default markers are too large cluttering race display
|
||||
/*
|
||||
* startMarker = new Marker(startPoint); map.addOverlay(startMarker); /*
|
||||
* startMarker.addMarkerMouseOverHandler(new MarkerMouseOverHandler () {
|
||||
*
|
||||
* @Override public void onMouseOver(MarkerMouseOverEvent event) { InfoWindowContent content = new
|
||||
* InfoWindowContent("Start"); map.getInfoWindow().open(startMarker, content); }
|
||||
*
|
||||
* });
|
||||
*
|
||||
* startMarker.addMarkerMouseOutHandler(new MarkerMouseOutHandler () {
|
||||
*
|
||||
* @Override public void onMouseOut(MarkerMouseOutEvent event) { map.getInfoWindow().close(); }
|
||||
*
|
||||
* });
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void setEndPoint(LatLng endPoint) {
|
||||
this.endPoint = endPoint;
|
||||
|
||||
if (endPoint != null) {
|
||||
Point point = mapProjection.fromLatLngToDivPixel(endPoint);
|
||||
drawCircleWithText(point.getX() - getWidgetPosLeft(), point.getY() - getWidgetPosTop(), racecourseBuoySize,
|
||||
racecourseColor, "End");
|
||||
|
||||
if (endMarker != null) {
|
||||
endMarker.setPosition(endPoint);
|
||||
} else {
|
||||
// default markers are too large cluttering race display
|
||||
/*
|
||||
* endMarker = new Marker(endPoint); map.addOverlay(endMarker);
|
||||
*
|
||||
* endMarker.addMarkerMouseOverHandler(new RaceCourseMarkerMouseOverHandler());
|
||||
*
|
||||
* endMarker.addMarkerMouseOutHandler(new MarkerMouseOutHandler() {
|
||||
*
|
||||
* @Override public void onMouseOut(MarkerMouseOutEvent event) { map.getInfoWindow().close(); }
|
||||
*
|
||||
* });
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -188,6 +144,59 @@ public class RaceCourseCanvasOverlay extends FullCanvasOverlay {
|
||||
if(mapProjection != null && startPoint != null && endPoint != null) {
|
||||
setCanvasSettings();
|
||||
setStartEndPoint(startPoint, endPoint);
|
||||
|
||||
if (startPoint != null) {
|
||||
|
||||
Point point = mapProjection.fromLatLngToDivPixel(startPoint);
|
||||
drawCircleWithText(point.getX() - getWidgetPosLeft(), point.getY() - getWidgetPosTop(), racecourseBuoySize,
|
||||
racecourseColor, "Start");
|
||||
if (startMarker != null) {
|
||||
startMarker.setPosition(startPoint);
|
||||
} else {
|
||||
// default markers are too large cluttering race display
|
||||
/*
|
||||
* startMarker = new Marker(startPoint); map.addOverlay(startMarker); /*
|
||||
* startMarker.addMarkerMouseOverHandler(new MarkerMouseOverHandler () {
|
||||
*
|
||||
* @Override public void onMouseOver(MarkerMouseOverEvent event) { InfoWindowContent content = new
|
||||
* InfoWindowContent("Start"); map.getInfoWindow().open(startMarker, content); }
|
||||
*
|
||||
* });
|
||||
*
|
||||
* startMarker.addMarkerMouseOutHandler(new MarkerMouseOutHandler () {
|
||||
*
|
||||
* @Override public void onMouseOut(MarkerMouseOutEvent event) { map.getInfoWindow().close(); }
|
||||
*
|
||||
* });
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (endPoint != null) {
|
||||
Point point = mapProjection.fromLatLngToDivPixel(endPoint);
|
||||
drawCircleWithText(point.getX() - getWidgetPosLeft(), point.getY() - getWidgetPosTop(), racecourseBuoySize,
|
||||
racecourseColor, "End");
|
||||
|
||||
if (endMarker != null) {
|
||||
endMarker.setPosition(endPoint);
|
||||
} else {
|
||||
// default markers are too large cluttering race display
|
||||
/*
|
||||
* endMarker = new Marker(endPoint); map.addOverlay(endMarker);
|
||||
*
|
||||
* endMarker.addMarkerMouseOverHandler(new RaceCourseMarkerMouseOverHandler());
|
||||
*
|
||||
* endMarker.addMarkerMouseOutHandler(new MarkerMouseOutHandler() {
|
||||
*
|
||||
* @Override public void onMouseOut(MarkerMouseOutEvent event) { map.getInfoWindow().close(); }
|
||||
*
|
||||
* });
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
drawLine(endPoint, racecourseColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,74 +2,119 @@ package com.sap.sailing.gwt.ui.simulator;
|
||||
|
||||
import com.google.gwt.canvas.dom.client.Context2d;
|
||||
import com.google.gwt.canvas.dom.client.Context2d.TextAlign;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.maps.client.MapWidget;
|
||||
import com.google.gwt.maps.client.base.LatLng;
|
||||
import com.google.gwt.maps.client.base.Point;
|
||||
import com.google.gwt.maps.client.events.click.ClickMapEvent;
|
||||
import com.google.gwt.maps.client.events.click.ClickMapHandler;
|
||||
import com.google.gwt.maps.client.events.mouseout.MouseOutMapEvent;
|
||||
import com.google.gwt.maps.client.events.mouseout.MouseOutMapHandler;
|
||||
import com.google.gwt.maps.client.events.idle.IdleMapEvent;
|
||||
import com.google.gwt.maps.client.events.idle.IdleMapHandler;
|
||||
import com.google.gwt.maps.client.overlays.Circle;
|
||||
import com.google.gwt.maps.client.overlays.CircleOptions;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.ImageTransformer;
|
||||
import com.sap.sailing.gwt.ui.simulator.racemap.FullCanvasOverlay;
|
||||
import com.sap.sailing.gwt.ui.simulator.util.SimulatorResources;
|
||||
import com.sap.sailing.simulator.util.SailingSimulatorConstants;
|
||||
|
||||
public class RegattaAreaCanvasOverlay extends FullCanvasOverlay {
|
||||
|
||||
private static SimulatorResources resources = GWT.create(SimulatorResources.class);
|
||||
|
||||
private SimulatorMap simulatorMap;
|
||||
private RaceCourseCanvasOverlay raceCourseCanvasOverlay;
|
||||
private VenueDescriptor venue;
|
||||
private CourseAreaDescriptor currentCourseArea = null;
|
||||
|
||||
private boolean pan;
|
||||
private boolean initial;
|
||||
private boolean mapPan = false;
|
||||
private double raceBearing = 0.0;
|
||||
private double diffBearing = 0.0;
|
||||
|
||||
private ImageTransformer windRoseBackground;
|
||||
private ImageTransformer windRoseNeedle;
|
||||
|
||||
public RegattaAreaCanvasOverlay(MapWidget map, int zIndex, char event) {
|
||||
super(map, zIndex);
|
||||
public RegattaAreaCanvasOverlay(MapWidget map, int zIndex, char event, final SimulatorMap simulatorMap) {
|
||||
|
||||
super(map, zIndex);
|
||||
|
||||
this.simulatorMap = simulatorMap;
|
||||
this.venue = VenueDescriptorFactory.createVenue(event);
|
||||
this.currentCourseArea = this.venue.getDefaultCourseArea();
|
||||
|
||||
/*getMap().addZoomChangeHandler(new ZoomChangeMapHandler() {
|
||||
|
||||
@Override
|
||||
public void onEvent(ZoomChangeMapEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
simulatorMap.windRoseCanvasOverlay.removeFromMap();
|
||||
simulatorMap.windNeedleCanvasOverlay.removeFromMap();
|
||||
mapPan = true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
getMap().addDragStartHandler(new DragStartMapHandler() {
|
||||
|
||||
@Override
|
||||
public void onEvent(DragStartMapEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
simulatorMap.windRoseCanvasOverlay.removeFromMap();
|
||||
simulatorMap.windNeedleCanvasOverlay.removeFromMap();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
getMap().addDragEndHandler(new DragEndMapHandler() {
|
||||
|
||||
@Override
|
||||
public void onEvent(DragEndMapEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
simulatorMap.windRoseCanvasOverlay.addToMap();
|
||||
simulatorMap.windNeedleCanvasOverlay.addToMap();
|
||||
}
|
||||
|
||||
|
||||
});*/
|
||||
|
||||
getMap().addIdleHandler(new IdleMapHandler() {
|
||||
|
||||
@Override
|
||||
public void onEvent(IdleMapEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
if (mapPan) {
|
||||
//System.out.println("Map Idle Event Handler.");
|
||||
simulatorMap.getWindRoseCanvasOverlay().addToMap();
|
||||
simulatorMap.getWindNeedleCanvasOverlay().addToMap();
|
||||
mapPan = false;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
windRoseBackground = new ImageTransformer(resources.windRoseBackground());
|
||||
windRoseNeedle = new ImageTransformer(resources.windRoseNeedle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToMap() {
|
||||
super.addToMap();
|
||||
|
||||
// TODO MigrationV3:
|
||||
// getPane().add(windRoseBackground.getCanvas(), getWidgetPosLeft() + windBackgroundOffset, getWidgetPosTop());
|
||||
// getPane().add(windRoseNeedle.getCanvas(), getWidgetPosLeft() + windBackgroundOffset + windNeedleOffset,
|
||||
// getWidgetPosTop() + windNeedleOffset);
|
||||
|
||||
int counter = 1;
|
||||
int counter = 0;
|
||||
for (CourseAreaDescriptor courseArea : venue.getCourseAreas()) {
|
||||
drawCircleFromRadius(counter++, courseArea);
|
||||
}
|
||||
|
||||
map.panTo(venue.getCenterPos());
|
||||
this.initial = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void draw() {
|
||||
|
||||
super.draw();
|
||||
|
||||
if(mapProjection != null) {
|
||||
// TODO MigrationV3:
|
||||
// getPane().setWidgetPosition(windRoseBackground.getCanvas(), getWidgetPosLeft() + windBackgroundOffset,
|
||||
// getWidgetPosTop());
|
||||
// getPane().setWidgetPosition(windRoseNeedle.getCanvas(),
|
||||
// getWidgetPosLeft() + windBackgroundOffset + windNeedleOffset, getWidgetPosTop() + windNeedleOffset);
|
||||
|
||||
clearCanvas();
|
||||
drawRegattaAreas();
|
||||
|
||||
if (this.initial) {
|
||||
updateRaceCourse(0, 0);
|
||||
this.initial = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,8 +124,6 @@ public class RegattaAreaCanvasOverlay extends FullCanvasOverlay {
|
||||
}
|
||||
|
||||
protected void drawRegattaAreas() {
|
||||
windRoseBackground.drawTransformedImage(0.0, 1.0);
|
||||
windRoseNeedle.drawTransformedImage(raceBearing + 180.0, 1.0);
|
||||
|
||||
LatLng cPos = LatLng.newInstance(54.4344, 10.19659167);
|
||||
Point centerPoint = mapProjection.fromLatLngToDivPixel(cPos);
|
||||
@@ -101,6 +144,7 @@ public class RegattaAreaCanvasOverlay extends FullCanvasOverlay {
|
||||
|
||||
// TODO MigrationV3: This is not the right place to create Circles being not drawn to the canvas -> move to SimulatorMap
|
||||
public void drawCircleFromRadius(int regIdx, CourseAreaDescriptor courseArea) {
|
||||
|
||||
CircleOptions circleOptions = CircleOptions.newInstance();
|
||||
circleOptions.setStrokeColor("white");
|
||||
circleOptions.setStrokeWeight(1);
|
||||
@@ -109,51 +153,47 @@ public class RegattaAreaCanvasOverlay extends FullCanvasOverlay {
|
||||
circleOptions.setFillOpacity(0.0);
|
||||
circleOptions.setCenter(courseArea.getCenterPos());
|
||||
Circle circle = Circle.newInstance(circleOptions);
|
||||
circle.setRadius(courseArea.getRadius());
|
||||
circle.setRadius(courseArea.getRadiusInMeters());
|
||||
|
||||
final int regIdxFinal = regIdx;
|
||||
|
||||
circle.addClickHandler(new ClickMapHandler() {
|
||||
public void onEvent(ClickMapEvent e) {
|
||||
// System.out.println("Click: "+currentRegArea.name);
|
||||
//System.out.println("Click: "+currentCourseArea.getName());
|
||||
CourseAreaDescriptor newRegArea = venue.getCourseAreas().get(regIdxFinal);
|
||||
|
||||
if (newRegArea != currentCourseArea) {
|
||||
currentCourseArea = newRegArea;
|
||||
// simulatorMap.clearOverlays();
|
||||
simulatorMap.clearOverlays();
|
||||
simulatorMap.getWindRoseCanvasOverlay().removeFromMap();
|
||||
simulatorMap.getWindNeedleCanvasOverlay().removeFromMap();
|
||||
updateRaceCourse(0, 0);
|
||||
raceCourseCanvasOverlay.draw();
|
||||
}
|
||||
|
||||
pan = true;
|
||||
map.panTo(currentCourseArea.getCenterPos());
|
||||
mapPan = true;
|
||||
if (map.getZoom() < 14) {
|
||||
map.setZoom(14);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
circle.setMap(getMap());
|
||||
getMap().addMouseOutMoveHandler(new MouseOutMapHandler() {
|
||||
public void onEvent(MouseOutMapEvent event) {
|
||||
if (pan) {
|
||||
pan = false;
|
||||
if (map.getZoom() < 14) {
|
||||
map.setZoom(14);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected void updateRaceCourse(int type, double bearing) {
|
||||
|
||||
if (type == 1) {
|
||||
raceBearing = bearing;
|
||||
windRoseNeedle.drawTransformedImage(raceBearing + 180.0, 1.0);
|
||||
simulatorMap.getWindNeedleCanvasOverlay().setBearing(raceBearing + 180.0);
|
||||
} else if (type == 2) {
|
||||
diffBearing = bearing;
|
||||
}
|
||||
if (currentCourseArea != null) {
|
||||
// simulatorMap.getMainPanel().setUpdateButtonEnabled(true);
|
||||
simulatorMap.getMainPanel().setUpdateButtonEnabled(true);
|
||||
LatLng startPoint;
|
||||
LatLng endPoint;
|
||||
if (raceCourseCanvasOverlay.raceCourseDirection == SailingSimulatorConstants.LegTypeDownwind) {
|
||||
@@ -165,7 +205,7 @@ public class RegattaAreaCanvasOverlay extends FullCanvasOverlay {
|
||||
}
|
||||
raceCourseCanvasOverlay.setStartEndPoint(startPoint, endPoint);
|
||||
} else {
|
||||
// simulatorMap.getMainPanel().setUpdateButtonEnabled(false);
|
||||
simulatorMap.getMainPanel().setUpdateButtonEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,14 +147,16 @@ public class SimulatorMainPanel extends SimplePanel {
|
||||
if (setting.getDisplayName().equals("Base Bearing (Degrees)")) {
|
||||
simulatorMap.clearOverlays();
|
||||
//System.out.println("Wind Base Bearing: "+setting.getValue());
|
||||
simulatorMap.regattaAreaCanvasOverlay.updateRaceCourse(1, (Double) setting.getValue());
|
||||
simulatorMap.raceCourseCanvasOverlay.draw();
|
||||
simulatorMap.getRegattaAreaCanvasOverlay().updateRaceCourse(1, (Double) setting.getValue());
|
||||
simulatorMap.getRaceCourseCanvasOverlay().draw();
|
||||
simulatorMap.getWindNeedleCanvasOverlay().draw();
|
||||
}
|
||||
if (setting.getDisplayName().equals("Race Course Diff (Degrees)")) {
|
||||
simulatorMap.clearOverlays();
|
||||
//System.out.println("Wind Base Bearing: "+setting.getValue());
|
||||
simulatorMap.regattaAreaCanvasOverlay.updateRaceCourse(2, (Double) setting.getValue());
|
||||
simulatorMap.raceCourseCanvasOverlay.draw();
|
||||
simulatorMap.getRegattaAreaCanvasOverlay().updateRaceCourse(2, (Double) setting.getValue());
|
||||
simulatorMap.getRaceCourseCanvasOverlay().draw();
|
||||
simulatorMap.getWindNeedleCanvasOverlay().draw();
|
||||
}
|
||||
if (autoUpdate) {
|
||||
update();
|
||||
@@ -834,7 +836,7 @@ public class SimulatorMainPanel extends SimplePanel {
|
||||
simulatorMap.refreshView(SimulatorMap.ViewName.WINDDISPLAY, currentWPDisplay, selection, true);
|
||||
} else if (summaryButton.getValue()) {
|
||||
showTimePanel(false);
|
||||
simulatorMap.regattaAreaCanvasOverlay.draw();
|
||||
simulatorMap.getRegattaAreaCanvasOverlay().draw();
|
||||
simulatorMap.refreshView(SimulatorMap.ViewName.SUMMARY, currentWPDisplay, selection, true);
|
||||
} else if (replayButton.getValue()) {
|
||||
showTimePanel(true);
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.logical.shared.ResizeEvent;
|
||||
import com.google.gwt.event.logical.shared.ResizeHandler;
|
||||
import com.google.gwt.maps.client.LoadApi;
|
||||
@@ -42,6 +43,7 @@ import com.sap.sailing.gwt.ui.shared.racemap.GoogleMapAPIKey;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.GoogleMapStyleHelper;
|
||||
import com.sap.sailing.gwt.ui.simulator.util.ColorPalette;
|
||||
import com.sap.sailing.gwt.ui.simulator.util.ColorPaletteGenerator;
|
||||
import com.sap.sailing.gwt.ui.simulator.util.SimulatorResources;
|
||||
import com.sap.sailing.gwt.ui.simulator.windpattern.WindPatternDisplay;
|
||||
import com.sap.sailing.simulator.util.SailingSimulatorConstants;
|
||||
|
||||
@@ -52,6 +54,9 @@ import com.sap.sailing.simulator.util.SailingSimulatorConstants;
|
||||
*
|
||||
*/
|
||||
public class SimulatorMap extends AbsolutePanel implements RequiresDataInitialization, TimeListenerWithStoppingCriteria {
|
||||
|
||||
private static SimulatorResources resources = GWT.create(SimulatorResources.class);
|
||||
|
||||
private MapWidget map;
|
||||
private boolean dataInitialized;
|
||||
private boolean overlaysInitialized;
|
||||
@@ -62,11 +67,13 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
private WindFieldCanvasOverlay windFieldCanvasOverlay;
|
||||
private WindGridCanvasOverlay windGridCanvasOverlay;
|
||||
private WindLineCanvasOverlay windLineCanvasOverlay;
|
||||
// TODO MigrationV3: should not be public
|
||||
public RegattaAreaCanvasOverlay regattaAreaCanvasOverlay;
|
||||
|
||||
private RegattaAreaCanvasOverlay regattaAreaCanvasOverlay;
|
||||
private ImageCanvasOverlay windRoseCanvasOverlay;
|
||||
private ImageCanvasOverlay windNeedleCanvasOverlay;
|
||||
private List<PathCanvasOverlay> replayPathCanvasOverlays;
|
||||
// TODO MigrationV3: should not be public
|
||||
public RaceCourseCanvasOverlay raceCourseCanvasOverlay;
|
||||
|
||||
private RaceCourseCanvasOverlay raceCourseCanvasOverlay;
|
||||
private PathLegendCanvasOverlay legendCanvasOverlay;
|
||||
|
||||
private List<TimeListenerWithStoppingCriteria> timeListeners;
|
||||
@@ -216,6 +223,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
refreshWindFieldOverlay(windFieldDTO);
|
||||
|
||||
timeListeners.clear();
|
||||
|
||||
if (windParams.isShowArrows()) {
|
||||
timeListeners.add(windFieldCanvasOverlay);
|
||||
}
|
||||
@@ -381,22 +389,31 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
}
|
||||
};
|
||||
|
||||
LoadApi.go(onLoad, loadLibraries, sensor, "key="+GoogleMapAPIKey.V2_APIKey);
|
||||
LoadApi.go(onLoad, loadLibraries, sensor, "key="+GoogleMapAPIKey.V2_APIKey);
|
||||
}
|
||||
|
||||
private void initializeOverlays() {
|
||||
if (mode == SailingSimulatorConstants.ModeEvent) {
|
||||
if (regattaAreaCanvasOverlay == null) {
|
||||
regattaAreaCanvasOverlay = new RegattaAreaCanvasOverlay(map, SimulatorMapOverlaysZIndexes.REGATTA_AREA_ZINDEX, getMainPanel().getEvent());
|
||||
regattaAreaCanvasOverlay = new RegattaAreaCanvasOverlay(map, SimulatorMapOverlaysZIndexes.REGATTA_AREA_ZINDEX, getMainPanel().getEvent(), this);
|
||||
regattaAreaCanvasOverlay.addToMap();
|
||||
|
||||
int offsetLeft = 50;
|
||||
int offsetTop = 25;
|
||||
windRoseCanvasOverlay = new ImageCanvasOverlay(map, SimulatorMapOverlaysZIndexes.WIND_ROSE_ZINDEX, resources.windRoseBackground());
|
||||
windRoseCanvasOverlay.setOffset(offsetLeft, offsetTop);
|
||||
windRoseCanvasOverlay.addToMap();
|
||||
windNeedleCanvasOverlay = new ImageCanvasOverlay(map, SimulatorMapOverlaysZIndexes.WIND_ROSE_ZINDEX, resources.windRoseNeedle());
|
||||
windNeedleCanvasOverlay.setOffset(offsetLeft, offsetTop);
|
||||
windNeedleCanvasOverlay.setBearing(180.0);
|
||||
windNeedleCanvasOverlay.addToMap();
|
||||
}
|
||||
}
|
||||
|
||||
raceCourseCanvasOverlay = new RaceCourseCanvasOverlay(map, SimulatorMapOverlaysZIndexes.RACE_COURSE_ZINDEX);
|
||||
raceCourseCanvasOverlay = new RaceCourseCanvasOverlay(map, SimulatorMapOverlaysZIndexes.RACE_COURSE_ZINDEX, mode);
|
||||
|
||||
if (mode == SailingSimulatorConstants.ModeEvent) {
|
||||
regattaAreaCanvasOverlay.setRaceCourseCanvas(raceCourseCanvasOverlay);
|
||||
regattaAreaCanvasOverlay.updateRaceCourse(0, 0);
|
||||
}
|
||||
|
||||
if (windParams.isShowArrows()) {
|
||||
@@ -460,6 +477,8 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
windParams.setxRes(xRes);
|
||||
windParams.setyRes(yRes);
|
||||
busyIndicator.setBusy(true);
|
||||
timer.setTime(windParams.getStartTime().getTime());
|
||||
|
||||
simulatorService.getWindField(windParams, windPatternDisplay, new AsyncCallback<WindFieldDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable message) {
|
||||
@@ -526,7 +545,6 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
}
|
||||
}
|
||||
|
||||
this.timer.setTime(this.windParams.getStartTime().getTime());
|
||||
if (this.windParams.isShowArrows()) {
|
||||
this.windFieldCanvasOverlay.draw();
|
||||
}
|
||||
@@ -563,6 +581,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
windParams.setyRes(yRes);
|
||||
|
||||
busyIndicator.setBusy(true);
|
||||
timer.setTime(windParams.getStartTime().getTime());
|
||||
|
||||
simulatorService.getSimulatorResults(mode, raceCourseDirection, windParams, windPatternDisplay, true, selection, new ResultManager(summaryView));
|
||||
|
||||
@@ -848,9 +867,27 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
raceCourseCanvasOverlay.raceCourseDirection = raceCourseDirection;
|
||||
regattaAreaCanvasOverlay.updateRaceCourse(0, 0);
|
||||
raceCourseCanvasOverlay.draw();
|
||||
windNeedleCanvasOverlay.draw();
|
||||
}
|
||||
|
||||
public WindFieldGenParamsDTO getWindParams() {
|
||||
return windParams;
|
||||
}
|
||||
|
||||
public RegattaAreaCanvasOverlay getRegattaAreaCanvasOverlay() {
|
||||
return regattaAreaCanvasOverlay;
|
||||
}
|
||||
|
||||
public ImageCanvasOverlay getWindRoseCanvasOverlay() {
|
||||
return windRoseCanvasOverlay;
|
||||
}
|
||||
|
||||
public ImageCanvasOverlay getWindNeedleCanvasOverlay() {
|
||||
return windNeedleCanvasOverlay;
|
||||
}
|
||||
|
||||
public RaceCourseCanvasOverlay getRaceCourseCanvasOverlay() {
|
||||
return raceCourseCanvasOverlay;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,12 +11,13 @@ public interface SimulatorMapOverlaysZIndexes {
|
||||
|
||||
public static int REGATTA_AREA_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 1;
|
||||
public static int RACE_COURSE_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 2;
|
||||
public static int WINDFIELD_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 3;
|
||||
public static int WINDSTREAMLETS_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 4;
|
||||
public static int WINDGRID_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 5;
|
||||
public static int WINDGRID_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 3;
|
||||
public static int WINDFIELD_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 4;
|
||||
public static int WINDSTREAMLETS_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 5;
|
||||
public static int WINDLINE_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 6;
|
||||
public static int PATH_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 7;
|
||||
public static int PATHLEGEND_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 8;
|
||||
public static int WIND_ROSE_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 8;
|
||||
public static int PATHLEGEND_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 9;
|
||||
|
||||
/** the z-index of the info window should always be higher than the rest */
|
||||
public static int INFO_WINDOW_ZINDEX = BASE_CANVAS_OVERLAY_ZINDEX + 50;
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.sap.sailing.gwt.ui.shared.WindFieldDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindFieldGenParamsDTO;
|
||||
import com.sap.sailing.gwt.ui.simulator.racemap.FullCanvasOverlay;
|
||||
import com.sap.sailing.gwt.ui.simulator.util.ToolTip;
|
||||
import com.sap.sailing.gwt.ui.simulator.util.WindFieldMapMouseMoveHandler;
|
||||
|
||||
/**
|
||||
* A google map overlay based on a HTML5 canvas for drawing a wind field. The overlay covers the whole map and displays
|
||||
@@ -44,8 +43,6 @@ public class WindFieldCanvasOverlay extends FullCanvasOverlay implements TimeLis
|
||||
protected Map<ToolTip, SimulatorWindDTO> windFieldPoints;
|
||||
protected String arrowColor = "Blue";
|
||||
protected String arrowHeadColor = "Blue";
|
||||
|
||||
protected WindFieldMapMouseMoveHandler mmHandler;
|
||||
|
||||
protected double arrowLength = 15;
|
||||
protected WindFieldGenParamsDTO windParams = null;
|
||||
@@ -93,11 +90,7 @@ public class WindFieldCanvasOverlay extends FullCanvasOverlay implements TimeLis
|
||||
@Override
|
||||
public void addToMap() {
|
||||
super.addToMap();
|
||||
if(mmHandler == null) {
|
||||
mmHandler = new WindFieldMapMouseMoveHandler(this);
|
||||
}
|
||||
mmHandler.setWindFieldPoints(windFieldPoints);
|
||||
mouseMoveHandlerRegistration = addMouseMoveHandler(mmHandler);
|
||||
|
||||
if (timer != null) {
|
||||
timer.addTimeListener(this);
|
||||
}
|
||||
@@ -127,7 +120,6 @@ public class WindFieldCanvasOverlay extends FullCanvasOverlay implements TimeLis
|
||||
canvas.getContext2d().clearRect(0.0 /*canvas.getAbsoluteLeft()*/, 0.0/*canvas.getAbsoluteTop()*/,
|
||||
canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
|
||||
windFieldPoints.clear();
|
||||
mmHandler.clear();
|
||||
}
|
||||
|
||||
protected void drawWindField() {
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.util.TreeMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.canvas.dom.client.Context2d;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.maps.client.MapWidget;
|
||||
import com.google.gwt.maps.client.base.LatLng;
|
||||
import com.google.gwt.maps.client.base.Point;
|
||||
@@ -23,7 +22,6 @@ import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindFieldDTO;
|
||||
import com.sap.sailing.gwt.ui.simulator.racemap.FullCanvasOverlay;
|
||||
import com.sap.sailing.gwt.ui.simulator.util.ToolTip;
|
||||
import com.sap.sailing.gwt.ui.simulator.util.WindFieldMapMouseMoveHandler;
|
||||
|
||||
/**
|
||||
* A google map overlay based on a HTML5 canvas for drawing a wind field. The overlay covers the whole map and displays
|
||||
@@ -33,7 +31,7 @@ import com.sap.sailing.gwt.ui.simulator.util.WindFieldMapMouseMoveHandler;
|
||||
*
|
||||
*/
|
||||
public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements TimeListenerWithStoppingCriteria {
|
||||
|
||||
|
||||
/** The wind field that is to be displayed in the overlay */
|
||||
private WindFieldDTO windFieldDTO;
|
||||
|
||||
@@ -46,8 +44,6 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
private Map<ToolTip, SimulatorWindDTO> windFieldPoints;
|
||||
private String arrowColor = "Black";
|
||||
private String arrowHeadColor = "Blue";
|
||||
private HandlerRegistration mouseMoveHandlerRegistration;
|
||||
private WindFieldMapMouseMoveHandler windFieldMapMouseMoveHandler;
|
||||
|
||||
private int xRes;
|
||||
private Timer timer;
|
||||
@@ -59,10 +55,9 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
|
||||
this.timer = timer;
|
||||
this.xRes = xRes;
|
||||
|
||||
|
||||
windFieldDTO = null;
|
||||
windFieldPoints = new HashMap<ToolTip, SimulatorWindDTO>();
|
||||
windFieldMapMouseMoveHandler = new WindFieldMapMouseMoveHandler(this);
|
||||
|
||||
timePointWindDTOMap = new TreeMap<Long, List<SimulatorWindDTO>>();
|
||||
}
|
||||
@@ -75,9 +70,6 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
public void addToMap() {
|
||||
super.addToMap();
|
||||
|
||||
windFieldMapMouseMoveHandler.setWindFieldPoints(windFieldPoints);
|
||||
mouseMoveHandlerRegistration = map.addMouseMoveHandler(windFieldMapMouseMoveHandler);
|
||||
|
||||
if (timer != null) {
|
||||
timer.addTimeListener(this);
|
||||
}
|
||||
@@ -87,8 +79,6 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
public void removeFromMap() {
|
||||
super.removeFromMap();
|
||||
|
||||
mouseMoveHandlerRegistration.removeHandler();
|
||||
|
||||
if (timer != null) {
|
||||
timer.removeTimeListener(this);
|
||||
}
|
||||
@@ -126,7 +116,6 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
canvas.getContext2d().clearRect(0.0 /*canvas.getAbsoluteLeft()*/, 0.0/*canvas.getAbsoluteTop()*/,
|
||||
canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
|
||||
windFieldPoints.clear();
|
||||
windFieldMapMouseMoveHandler.clear();
|
||||
}
|
||||
|
||||
protected void drawWindField() {
|
||||
|
||||
@@ -7,6 +7,8 @@ import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.maps.client.MapWidget;
|
||||
import com.google.gwt.maps.client.base.LatLng;
|
||||
import com.google.gwt.maps.client.base.Point;
|
||||
import com.google.gwt.maps.client.events.center.CenterChangeMapEvent;
|
||||
import com.google.gwt.maps.client.events.center.CenterChangeMapHandler;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.sap.sailing.domain.common.dto.PositionDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
|
||||
@@ -35,6 +37,23 @@ public abstract class FullCanvasOverlay extends CanvasOverlayV3 implements Requi
|
||||
|
||||
public FullCanvasOverlay(MapWidget map, int zIndex) {
|
||||
super(map, zIndex);
|
||||
|
||||
/*getMap().addDragEndHandler( new DragEndMapHandler() {
|
||||
@Override
|
||||
public void onEvent(DragEndMapEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
draw();
|
||||
};
|
||||
});*/
|
||||
|
||||
getMap().addCenterChangeHandler(new CenterChangeMapHandler() {
|
||||
@Override
|
||||
public void onEvent(CenterChangeMapEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
draw();
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.sap.sailing.gwt.ui.simulator.util;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gwt.canvas.dom.client.Context2d;
|
||||
import com.google.gwt.canvas.dom.client.ImageData;
|
||||
import com.google.gwt.i18n.client.NumberFormat;
|
||||
import com.google.gwt.maps.client.base.LatLng;
|
||||
import com.google.gwt.maps.client.base.Point;
|
||||
import com.google.gwt.maps.client.events.mousemove.MouseMoveMapEvent;
|
||||
import com.google.gwt.maps.client.events.mousemove.MouseMoveMapHandler;
|
||||
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
|
||||
import com.sap.sailing.gwt.ui.simulator.racemap.FullCanvasOverlay;
|
||||
|
||||
/**
|
||||
* To handle MouseMoveEvent to display tool tips around SimulatorWindDTO objects in a wind field
|
||||
*
|
||||
* @author Nidhi Sawhney(D054070)
|
||||
*
|
||||
*/
|
||||
public class WindFieldMapMouseMoveHandler implements MouseMoveMapHandler {
|
||||
|
||||
private final FullCanvasOverlay canvasOverlay;
|
||||
private Map<ToolTip, SimulatorWindDTO> windFieldPoints = null;
|
||||
private ImageData lastImageData = null;
|
||||
private double lastToolx;
|
||||
private double lastTooly;
|
||||
|
||||
public WindFieldMapMouseMoveHandler(final FullCanvasOverlay canvasOverlay) {
|
||||
super();
|
||||
this.canvasOverlay = canvasOverlay;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
lastImageData = null;
|
||||
}
|
||||
|
||||
public void setWindFieldPoints(final Map<ToolTip, SimulatorWindDTO> windFieldPoints) {
|
||||
this.windFieldPoints = windFieldPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(final MouseMoveMapEvent event) {
|
||||
if (windFieldPoints != null) {
|
||||
final LatLng latLng = event.getMouseEvent().getLatLng();
|
||||
final Point pointP = canvasOverlay.getMapProjection().fromLatLngToDivPixel(latLng);
|
||||
final double x = pointP.getX() - canvasOverlay.getWidgetPosLeft();
|
||||
final double y = pointP.getY() - canvasOverlay.getWidgetPosTop();
|
||||
final ToolTip point = new ToolTip(x, y);
|
||||
final Context2d context2d = canvasOverlay.getCanvas().getContext2d();
|
||||
if (lastImageData != null) {
|
||||
context2d.putImageData(lastImageData, lastToolx, lastTooly);
|
||||
}
|
||||
|
||||
if (windFieldPoints.containsKey(point)) {
|
||||
lastToolx = x;
|
||||
lastTooly = y;
|
||||
lastImageData = context2d.getImageData(x, y, ToolTip.toolRectW, ToolTip.toolRectH);
|
||||
|
||||
final SimulatorWindDTO windDTO = windFieldPoints.get(point);
|
||||
context2d.setFillStyle("#4f4f4f");
|
||||
context2d.fillRect(x, y, ToolTip.toolRectW, ToolTip.toolRectH);
|
||||
|
||||
context2d.setFillStyle("#FFFFFF");
|
||||
context2d.fillRect(x + 3, y + 3, ToolTip.toolRectW - 6, ToolTip.toolRectH - 6);
|
||||
|
||||
context2d.setFillStyle("Blue");
|
||||
final String speedStr = NumberFormat.getFormat("#.00").format(windDTO.trueWindSpeedInKnots);
|
||||
final String bearingStr = NumberFormat.getFormat("#.00").format(windDTO.trueWindBearingDeg);
|
||||
final String ttMsg = speedStr + " kn " + bearingStr + "�";
|
||||
context2d.fillText(ttMsg, x+10,y+15,60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -31,7 +31,7 @@ public abstract class AbstractMongoDBTest {
|
||||
}
|
||||
|
||||
protected Mongo newMongo() throws UnknownHostException, MongoException {
|
||||
return new Mongo(System.getProperty("mongo.host", "127.0.0.1"), dbConfiguration.getPort());
|
||||
return new Mongo(dbConfiguration.getHostName(), dbConfiguration.getPort());
|
||||
}
|
||||
|
||||
@Before
|
||||
|
||||
@@ -60,7 +60,7 @@ public class TestStoringAndRetrievingWindTracksTest extends AbstractTracTracLive
|
||||
}
|
||||
|
||||
private Mongo newMongo() throws UnknownHostException, MongoException {
|
||||
return new Mongo(System.getProperty("mongo.host", "127.0.0.1"),
|
||||
return new Mongo(dbConfiguration.getHostName(),
|
||||
dbConfiguration.getPort());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,16 +19,46 @@ public class MongoDBConfiguration {
|
||||
private String databaseName;
|
||||
|
||||
public static MongoDBConfiguration getDefaultConfiguration() {
|
||||
String defaultHostName = System.getProperty(MONGO_HOSTNAME, "127.0.0.1");
|
||||
int defaultPort = Integer.valueOf(System.getProperty(MONGO_PORT, "27017"));
|
||||
String defaultHostName = "127.0.0.1";
|
||||
if (System.getProperty(MONGO_HOSTNAME) != null) {
|
||||
defaultHostName = System.getProperty(MONGO_HOSTNAME);
|
||||
} else {
|
||||
if (System.getenv("MONGODB_HOST") != null) {
|
||||
defaultHostName = System.getenv("MONGODB_HOST");
|
||||
}
|
||||
}
|
||||
|
||||
int defaultPort = 27017;
|
||||
if (System.getProperty(MONGO_PORT) != null) {
|
||||
defaultPort = Integer.valueOf(System.getProperty(MONGO_PORT).trim());
|
||||
} else {
|
||||
if (System.getenv("MONGODB_PORT") != null) {
|
||||
defaultPort = Integer.valueOf(System.getenv("MONGODB_PORT").trim());
|
||||
}
|
||||
}
|
||||
String defaultDatabaseName = System.getProperty(MONGO_DB_NAME, DEFAULT_DB_NAME);
|
||||
|
||||
return new MongoDBConfiguration(defaultHostName, defaultPort, defaultDatabaseName);
|
||||
}
|
||||
|
||||
public static MongoDBConfiguration getDefaultTestConfiguration() {
|
||||
String defaultHostName = System.getProperty(MONGO_HOSTNAME, "127.0.0.1");
|
||||
int defaultPort = Integer.valueOf(System.getProperty(MONGO_PORT, "27017"));
|
||||
String defaultHostName = "127.0.0.1";
|
||||
if (System.getProperty(MONGO_HOSTNAME) != null) {
|
||||
defaultHostName = System.getProperty(MONGO_HOSTNAME);
|
||||
} else {
|
||||
if (System.getenv("MONGODB_HOST") != null) {
|
||||
defaultHostName = System.getenv("MONGODB_HOST");
|
||||
}
|
||||
}
|
||||
|
||||
int defaultPort = 27017;
|
||||
if (System.getProperty(MONGO_PORT) != null) {
|
||||
defaultPort = Integer.valueOf(System.getProperty(MONGO_PORT).trim());
|
||||
} else {
|
||||
if (System.getenv("MONGODB_PORT") != null) {
|
||||
defaultPort = Integer.valueOf(System.getenv("MONGODB_PORT").trim());
|
||||
}
|
||||
}
|
||||
String defaultDatabaseName = System.getProperty(MONGO_DB_NAME, DEFAULT_TEST_DB_NAME);
|
||||
|
||||
return new MongoDBConfiguration(defaultHostName, defaultPort, defaultDatabaseName);
|
||||
|
||||
@@ -110,6 +110,10 @@ public class ESS40ResultsAsCSVServlet extends AbstractCSVHttpServlet {
|
||||
csvLine.add(maxPointsReason.name());
|
||||
csvLine.add(totalRacePoints);
|
||||
}
|
||||
} else {
|
||||
/* Make sure to also include null columns */
|
||||
csvLine.add(0);
|
||||
csvLine.add(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
import com.sap.sailing.server.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sailing.server.replication.ReplicationService;
|
||||
import com.sap.sailing.server.replication.impl.Activator;
|
||||
import com.sap.sailing.server.replication.impl.ReplicaDescriptor;
|
||||
import com.sap.sailing.server.replication.impl.ReplicationInstancesManager;
|
||||
import com.sap.sailing.server.replication.impl.ReplicationMasterDescriptorImpl;
|
||||
@@ -72,8 +73,11 @@ public abstract class AbstractServerReplicationTest {
|
||||
*/
|
||||
protected Pair<ReplicationServiceTestImpl, ReplicationMasterDescriptor> basicSetUp(
|
||||
boolean dropDB, RacingEventServiceImpl master, RacingEventServiceImpl replica) throws IOException, InterruptedException {
|
||||
final String exchangeName = "test-sapsailinganalytics-exchange";
|
||||
final String exchangeHost = "localhost";
|
||||
String exchangeName = "test-sapsailinganalytics-exchange";
|
||||
String exchangeHost = "localhost";
|
||||
if (System.getenv(Activator.REPLICATION_HOST) != null) {
|
||||
exchangeHost = System.getenv(Activator.REPLICATION_HOST);
|
||||
}
|
||||
final UUID serverUuid = UUID.randomUUID();
|
||||
final MongoDBService mongoDBService = MongoDBService.INSTANCE;
|
||||
if (dropDB) {
|
||||
@@ -94,7 +98,9 @@ public abstract class AbstractServerReplicationTest {
|
||||
masterReplicator = new ReplicationServiceImpl(exchangeName, exchangeHost, rim, this.master);
|
||||
replicaDescriptor = new ReplicaDescriptor(InetAddress.getLocalHost(), serverUuid, "");
|
||||
masterReplicator.registerReplica(replicaDescriptor);
|
||||
masterDescriptor = new ReplicationMasterDescriptorImpl("localhost", exchangeName, SERVLET_PORT, 0, UUID.randomUUID().toString());
|
||||
// connect to exchange host and local server running as master
|
||||
// master server and exchange host can be two different hosts
|
||||
masterDescriptor = new ReplicationMasterDescriptorImpl(exchangeHost, "localhost", exchangeName, SERVLET_PORT, 0, UUID.randomUUID().toString());
|
||||
ReplicationServiceTestImpl replicaReplicator = new ReplicationServiceTestImpl(exchangeName, exchangeHost, resolveAgainst, rim,
|
||||
replicaDescriptor, this.replica, this.master, masterReplicator, masterDescriptor);
|
||||
Pair<ReplicationServiceTestImpl, ReplicationMasterDescriptor> result = new Pair<>(replicaReplicator, masterDescriptor);
|
||||
|
||||
@@ -49,12 +49,12 @@ public class ConnectionResetAndReconnectTest extends AbstractServerReplicationTe
|
||||
|
||||
static class MasterReplicationDescriptorMock extends ReplicationMasterDescriptorImpl {
|
||||
|
||||
public MasterReplicationDescriptorMock(String hostname, String exchangeName, int servletPort, int messagingPort) {
|
||||
super(hostname, exchangeName, servletPort, messagingPort, UUID.randomUUID().toString());
|
||||
public MasterReplicationDescriptorMock(String messagingHost, String hostname, String exchangeName, int servletPort, int messagingPort) {
|
||||
super(messagingHost, hostname, exchangeName, servletPort, messagingPort, UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
public static MasterReplicationDescriptorMock from(ReplicationMasterDescriptor obj) {
|
||||
return new MasterReplicationDescriptorMock(obj.getHostname(), obj.getExchangeName(), obj.getServletPort(), obj.getMessagingPort());
|
||||
return new MasterReplicationDescriptorMock(obj.getMessagingHostname(), obj.getHostname(), obj.getExchangeName(), obj.getServletPort(), obj.getMessagingPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,5 +5,5 @@ import com.sap.sailing.server.replication.impl.ReplicationFactoryImpl;
|
||||
public interface ReplicationFactory {
|
||||
static ReplicationFactory INSTANCE = new ReplicationFactoryImpl();
|
||||
|
||||
ReplicationMasterDescriptor createReplicationMasterDescriptor(String hostname, String exchangeName, int servletPort, int jmsPort, String jmsQueueName);
|
||||
ReplicationMasterDescriptor createReplicationMasterDescriptor(String messagingHostname, String hostname, String exchangeName, int servletPort, int jmsPort, String jmsQueueName);
|
||||
}
|
||||
@@ -38,4 +38,6 @@ public interface ReplicationMasterDescriptor {
|
||||
String getExchangeName();
|
||||
|
||||
void stopConnection();
|
||||
|
||||
String getMessagingHostname();
|
||||
}
|
||||
@@ -12,6 +12,9 @@ public class Activator implements BundleActivator {
|
||||
|
||||
private static final String PROPERTY_NAME_EXCHANGE_NAME = "replication.exchangeName";
|
||||
private static final String PROPERTY_NAME_EXCHANGE_HOST = "replication.exchangeHost";
|
||||
|
||||
public static final String REPLICATION_CHANNEL = "REPLICATION_CHANNEL";
|
||||
public static final String REPLICATION_HOST = "REPLICATION_HOST";
|
||||
|
||||
private ReplicationInstancesManager replicationInstancesManager;
|
||||
|
||||
@@ -22,15 +25,23 @@ public class Activator implements BundleActivator {
|
||||
String exchangeName = bundleContext.getProperty(PROPERTY_NAME_EXCHANGE_NAME);
|
||||
String exchangeHost = bundleContext.getProperty(PROPERTY_NAME_EXCHANGE_HOST);
|
||||
if (exchangeName == null) {
|
||||
exchangeName = "sapsailinganalytics";
|
||||
if (System.getenv(REPLICATION_CHANNEL) == null) {
|
||||
exchangeName = "sapsailinganalytics";
|
||||
} else {
|
||||
exchangeName = System.getenv(REPLICATION_CHANNEL);
|
||||
}
|
||||
}
|
||||
if (exchangeHost == null) {
|
||||
exchangeHost = "localhost";
|
||||
if (System.getenv(REPLICATION_HOST) == null) {
|
||||
exchangeHost = "localhost";
|
||||
} else {
|
||||
exchangeHost = System.getenv(REPLICATION_HOST);
|
||||
}
|
||||
}
|
||||
replicationInstancesManager = new ReplicationInstancesManager();
|
||||
ReplicationService serverReplicationMasterService = new ReplicationServiceImpl(exchangeName, exchangeHost, replicationInstancesManager);
|
||||
bundleContext.registerService(ReplicationService.class, serverReplicationMasterService, null);
|
||||
logger.info("Registered replication service "+serverReplicationMasterService+" using exchange name "+exchangeName);
|
||||
logger.info("Registered replication service "+serverReplicationMasterService+" using exchange name "+exchangeName+" on host "+exchangeHost);
|
||||
}
|
||||
|
||||
public void stop(BundleContext bundleContext) throws Exception {
|
||||
|
||||
@@ -5,8 +5,8 @@ import com.sap.sailing.server.replication.ReplicationMasterDescriptor;
|
||||
|
||||
public class ReplicationFactoryImpl implements ReplicationFactory {
|
||||
@Override
|
||||
public ReplicationMasterDescriptor createReplicationMasterDescriptor(String hostname, String exchangeName, int servletPort, int messagingPort, String queueName) {
|
||||
return new ReplicationMasterDescriptorImpl(hostname, exchangeName, servletPort, messagingPort, queueName);
|
||||
public ReplicationMasterDescriptor createReplicationMasterDescriptor(String messagingHostname, String hostname, String exchangeName, int servletPort, int messagingPort, String queueName) {
|
||||
return new ReplicationMasterDescriptorImpl(messagingHostname, hostname, exchangeName, servletPort, messagingPort, queueName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescrip
|
||||
private final String hostname;
|
||||
private final String exchangeName;
|
||||
private final int servletPort;
|
||||
private final String messagingHostname;
|
||||
private final int messagingPort;
|
||||
private final String queueName;
|
||||
|
||||
@@ -28,8 +29,9 @@ public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescrip
|
||||
/**
|
||||
* @param messagingPort 0 means use default port
|
||||
*/
|
||||
public ReplicationMasterDescriptorImpl(String hostname, String exchangeName, int servletPort, int messagingPort, String queueName) {
|
||||
public ReplicationMasterDescriptorImpl(String messagingHostname, String hostname, String exchangeName, int servletPort, int messagingPort, String queueName) {
|
||||
this.hostname = hostname;
|
||||
this.messagingHostname = messagingHostname;
|
||||
this.servletPort = servletPort;
|
||||
this.messagingPort = messagingPort;
|
||||
this.exchangeName = exchangeName;
|
||||
@@ -39,7 +41,7 @@ public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescrip
|
||||
|
||||
@Override
|
||||
public URL getReplicationRegistrationRequestURL(UUID uuid, String additional) throws MalformedURLException, UnsupportedEncodingException {
|
||||
return new URL("http", hostname, servletPort, REPLICATION_SERVLET + "?" + ReplicationServlet.ACTION + "="
|
||||
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"));
|
||||
@@ -47,21 +49,21 @@ public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescrip
|
||||
|
||||
@Override
|
||||
public URL getReplicationDeRegistrationRequestURL(UUID uuid) throws MalformedURLException {
|
||||
return new URL("http", hostname, servletPort, REPLICATION_SERVLET + "?" + ReplicationServlet.ACTION + "="
|
||||
return new URL("http", getHostname(), servletPort, REPLICATION_SERVLET + "?" + ReplicationServlet.ACTION + "="
|
||||
+ ReplicationServlet.Action.DEREGISTER.name()
|
||||
+ "&" + ReplicationServlet.SERVER_UUID + "=" + uuid.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getInitialLoadURL() throws MalformedURLException {
|
||||
return new URL("http", hostname, servletPort, REPLICATION_SERVLET + "?" + ReplicationServlet.ACTION + "="
|
||||
return new URL("http", getHostname(), servletPort, REPLICATION_SERVLET + "?" + ReplicationServlet.ACTION + "="
|
||||
+ ReplicationServlet.Action.INITIAL_LOAD.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized QueueingConsumer getConsumer() throws IOException {
|
||||
ConnectionFactory connectionFactory = new ConnectionFactory();
|
||||
connectionFactory.setHost(getHostname());
|
||||
connectionFactory.setHost(getMessagingHostname());
|
||||
int port = getMessagingPort();
|
||||
if (port != 0) {
|
||||
connectionFactory.setPort(port);
|
||||
@@ -137,6 +139,11 @@ public class ReplicationMasterDescriptorImpl implements ReplicationMasterDescrip
|
||||
public int getMessagingPort() {
|
||||
return messagingPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessagingHostname() {
|
||||
return messagingHostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServletPort() {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console -clean"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=2010 -Xmx6000m -Dhttp.proxyHost=proxy.wdf.sap.corp -Dhttp.proxyPort=8080 -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -XX:+UseMembar"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=2010 -Xmx6000m -Dhttp.proxyHost=proxy.wdf.sap.corp -Dhttp.proxyPort=8080 -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -XX:+UseMembar"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
|
||||
<stringAttribute key="pde.version" value="3.3"/>
|
||||
<booleanAttribute key="show_selected_only" value="false"/>
|
||||
|
||||
@@ -9,7 +9,9 @@ public interface SailingSimulatorConstants {
|
||||
public static final char LegTypeUpwind = 'u'; // leg type: 'u'pwind
|
||||
public static final char LegTypeDownwind = 'd'; // leg type: 'd'ownwind
|
||||
|
||||
public static final char EventDummy = '0'; // used in cases where race course is defined as URL parameter
|
||||
public static final char EventKielerWoche = 'k'; // event: 'k'ieler woche
|
||||
public static final char EventTravemuenderWoche = 't'; // event: 't'ravemünder woche
|
||||
public static final char EventX40Cardiff = 'c'; // event: 'c'ardiff extreme sailing series
|
||||
|
||||
}
|
||||
@@ -22,9 +22,27 @@ REPLICATE_MASTER_SERVLET_PORT=
|
||||
REPLICATE_MASTER_QUEUE_HOST=
|
||||
REPLICATE_MASTER_QUEUE_PORT=
|
||||
|
||||
# Automatic build and test configuration
|
||||
DEPLOY_TO=
|
||||
BUILD_BEFORE_START=False
|
||||
BUILD_FROM=master
|
||||
COMPILE_GWT=True
|
||||
RUN_TESTS=False
|
||||
CODE_DIRECTORY=code
|
||||
BUILD_COMPLETE_NOTIFY=simon.marcel.pamies@sap.com
|
||||
|
||||
# Specify an email address that should be notified
|
||||
# whenever the server has been started
|
||||
SERVER_STARTUP_NOTIFY=
|
||||
|
||||
INSTANCE_ID="$SERVER_NAME:$SERVER_PORT"
|
||||
ADDITIONAL_JAVA_ARGS="-XX:+UseMembar"
|
||||
|
||||
JAVA_HOME=$HOME/jdk1.7.0_02
|
||||
if [[ ! -d $JAVA_HOME ]] && [[ -f "/usr/libexec/java_home" ]]; then
|
||||
JAVA_HOME=`/usr/libexec/java_home`
|
||||
echo "Setting JAVA_HOME to discovered $JAVA_HOME"
|
||||
fi
|
||||
|
||||
# Make it possible to overwrite configuration
|
||||
# by using user-data that is injected into an instance
|
||||
@@ -36,5 +54,13 @@ if [[ ! -z "$ON_AMAZON" ]]; then
|
||||
echo $var
|
||||
export $var
|
||||
done
|
||||
|
||||
# set directory where to deploy code to
|
||||
# this is fixed on EC2 instances
|
||||
DEPLOY_TO=server
|
||||
INSTANCE_NAME=`ec2-metadata -i | cut -f2 -d " "`
|
||||
INSTANCE_IP4=`ec2-metadata -v | cut -f2 -d " "`
|
||||
INSTANCE_DNS=`ec2-metadata -p | cut -f2 -d " "`
|
||||
INSTANCE_ID="$INSTANCE_NAME ($INSTANCE_IP4)"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh
|
||||
target="`dirname \"$0\"`"
|
||||
pwd=`pwd`
|
||||
echo "$target" | grep "^/"
|
||||
if [ "$0" != "0" ]; then
|
||||
# no leading slash, therefore no absolute path; prepend pwd
|
||||
target="$pwd/$target"
|
||||
fi
|
||||
echo target is $target
|
||||
pluginsdir="$target/../com.sap.sailing.feature.p2build/bin/products/raceanalysis.product.id/win32/win32/x86_64/plugins"
|
||||
mkdir resources
|
||||
classpath="`find $pluginsdir -name 'com.sap.sailing.domain_*.jar' | sort | tail -1`:`find $pluginsdir -name 'com.sap.sailing.domain.common_*.jar' | sort | tail -1`:`find $pluginsdir -name 'com.sap.sailing.domain.shared.android_*.jar' | sort | tail -1`:`find $pluginsdir -name 'com.sap.sailing.declination*.jar' | sort | tail -1`"
|
||||
echo Using classpath $classpath
|
||||
"$JAVA_HOME/bin/java" -cp "$classpath" -Djava.util.logging.config.file=$target/configuration/logging.properties com.sap.sailing.declination.impl.DeclinationStore $*
|
||||
@@ -0,0 +1,96 @@
|
||||
#!/bin/sh
|
||||
|
||||
. `pwd`/env.sh
|
||||
|
||||
checks ()
|
||||
{
|
||||
USER_HOME=~
|
||||
START_DIR=`pwd`
|
||||
PROJECT_HOME=$(find_project_home $START_DIR)
|
||||
|
||||
# needed for maven on sapsailing.com to work correctly
|
||||
if [ -f $USER_HOME/.bash_profile ]; then
|
||||
source $USER_HOME/.bash_profile
|
||||
fi
|
||||
|
||||
JAVA_BINARY=$JAVA_HOME/bin/java
|
||||
if [[ ! -d "$JAVA_HOME" ]]; then
|
||||
echo "Could not find $JAVA_BINARY set in env.sh. Trying to find the correct one..."
|
||||
JAVA_VERSION=$(java -version 2>&1 | sed 's/java version "\(.*\)\.\(.*\)\..*"/\1\2/; 1q')
|
||||
if [ "$JAVA_VERSION" -lt 17 ]; then
|
||||
echo "The current Java version ($JAVA_VERSION) does not match the requirements (>= 1.7)."
|
||||
exit 10
|
||||
fi
|
||||
JAVA_BINARY=`which java`
|
||||
echo "Using Java from $JAVA_BINARY"
|
||||
fi
|
||||
}
|
||||
|
||||
find_project_home ()
|
||||
{
|
||||
if [[ $1 == '/' ]] || [[ $1 == "" ]]; then
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ ! -d "$1/.git" ]; then
|
||||
PARENT_DIR=`cd $1/..;pwd`
|
||||
OUTPUT=$(find_project_home $PARENT_DIR)
|
||||
|
||||
if [ "$OUTPUT" = "" ] && [ -d "$PARENT_DIR/$CODE_DIRECTORY" ] && [ -d "$PARENT_DIR/$CODE_DIRECTORY/.git" ]; then
|
||||
OUTPUT="$PARENT_DIR/$CODE_DIRECTORY"
|
||||
fi
|
||||
echo $OUTPUT
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo $1 | sed -e 's/\/cygdrive\/\([a-zA-Z]\)/\1:/'
|
||||
}
|
||||
|
||||
checkout_code ()
|
||||
{
|
||||
cd $PROJECT_HOME
|
||||
GIT_BINARY=`which git`
|
||||
if [[ $COMPILE_GWT == "True" ]]; then
|
||||
# only reset if GWT gets compiled
|
||||
# if not p2build will not work
|
||||
$GIT_BINARY reset --hard
|
||||
fi
|
||||
$GIT_BINARY checkout $BUILD_FROM
|
||||
$GIT_BINARY pull
|
||||
}
|
||||
|
||||
build ()
|
||||
{
|
||||
cd $PROJECT_HOME
|
||||
TESTS="-t"
|
||||
if [[ $RUN_TESTS == "True" ]]; then
|
||||
TESTS=""
|
||||
fi
|
||||
GWT="-g"
|
||||
if [[ $COMPILE_GWT == "True" ]]; then
|
||||
GWT=""
|
||||
fi
|
||||
$PROJECT_HOME/configuration/buildAndUpdateProduct.sh $TESTS $GWT -u build
|
||||
STATUS=$?
|
||||
if [ $STATUS -eq 0 ]; then
|
||||
echo "Build Successful"
|
||||
else
|
||||
echo "Build Failed"
|
||||
exit 10
|
||||
fi
|
||||
}
|
||||
|
||||
deploy ()
|
||||
{
|
||||
cd $PROJECT_HOME
|
||||
if [[ $DEPLOY_TO != "" ]]; then
|
||||
DEPLOY="-s $DEPLOY_TO"
|
||||
fi
|
||||
$PROJECT_HOME/configuration/buildAndUpdateProduct.sh -u $DEPLOY install
|
||||
}
|
||||
|
||||
checks
|
||||
checkout_code
|
||||
build
|
||||
deploy
|
||||
@@ -3,6 +3,31 @@
|
||||
# source variables
|
||||
. `pwd`/env.sh
|
||||
|
||||
# check if automatic tests and build should be executed
|
||||
# before starting up the server
|
||||
if [[ $BUILD_BEFORE_START == "True" ]]; then
|
||||
|
||||
# check for available memory - build can not be started with less than 1GB
|
||||
MEM_TOTAL=`free -mt | grep Total | awk '{print $2}'`
|
||||
if [ $MEM_TOTAL -lt 924 ]; then
|
||||
echo "Could not start build process with less than 1GB of RAM!"
|
||||
echo "Not enough RAM for completing the build process! You need at least 1GB. Instance NOT started!" | `which mail` -r simon.marcel.pamies@sap.com -s "Build of $INSTANCE_ID failed" $BUILD_COMPLETE_NOTIFY
|
||||
exit 10
|
||||
fi
|
||||
|
||||
echo "Build process has been started - it can take 5 to 20 minutes until your instance is ready." | `which mail` -r simon.marcel.pamies@sap.com -s "Build of $INSTANCE_ID starting" $BUILD_COMPLETE_NOTIFY
|
||||
`pwd`/shouldIBuildOrShouldIGo.sh &> last_automatic_build.txt
|
||||
STATUS=$?
|
||||
if [ $STATUS -eq 0 ]; then
|
||||
echo "Deployment Successful"
|
||||
echo "OK" | `which mail` -a last_automatic_build.txt -r simon.marcel.pamies@sap.com -s "Build of $INSTANCE_ID complete" $BUILD_COMPLETE_NOTIFY
|
||||
else
|
||||
echo "Deployment Failed"
|
||||
echo "ERROR" | `which mail` -a last_automatic_build.txt -r simon.marcel.pamies@sap.com -s "Build of $INSTANCE_ID failed" $BUILD_COMPLETE_NOTIFY
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
PARAM=$@
|
||||
|
||||
# make some checks
|
||||
@@ -54,12 +79,16 @@ REPLICATION_PARAMETERS="-Dreplication.start=$REPLICATE_ON_START -Dreplicate.mast
|
||||
|
||||
if [[ $PARAM == "" ]]; then
|
||||
nohup $JAVA_BINARY -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir=`pwd`/tmp -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -console $TELNET_PORT -configuration ./ -clean 2>/dev/null >/dev/null &
|
||||
echo "Starting server..."
|
||||
JAVA_PID=$!
|
||||
echo "Starting server... (PID: $JAVA_PID)"
|
||||
sleep 10
|
||||
|
||||
TELNET_ACTIVE=`netstat -tlnp 2>/dev/null | grep ":$TELNET_PORT"`
|
||||
if [[ $TELNET_PORT == "" ]] || [[ $TELNET_ACTIVE == "" ]]; then
|
||||
SERVER_ACTIVE=`netstat -tlnp 2>/dev/null | grep ":$SERVER_PORT"`
|
||||
if [[ $SERVER_PORT == "" ]] || [[ $SERVER_ACTIVE == "" ]]; then
|
||||
echo "Something went wrong with startup. Please check the logs..."
|
||||
if [[ $SERVER_STARTUP_NOTIFY != "" ]]; then
|
||||
echo "Startup of java server failed - check the logs" | `which mail` -r simon.marcel.pamies@sap.com -s "Server $INSTANCE_ID startup failed!" $SERVER_STARTUP_NOTIFY
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
|
||||
@@ -72,8 +101,16 @@ if [[ $PARAM == "" ]]; then
|
||||
echo "EXPEDITION_PORT: $EXPEDITION_PORT"
|
||||
echo "REPLICATION_CHANNEL: $REPLICATION_CHANNEL"
|
||||
echo "Started $SERVER_NAME - use telnet localhost $TELNET_PORT to connect to the OSGi console. Logs should be found in logs/sailing0.log.0"
|
||||
|
||||
if [[ $SERVER_STARTUP_NOTIFY != "" ]]; then
|
||||
if [[ ! -z "$ON_AMAZON" ]]; then
|
||||
echo "Go to http://$INSTANCE_DNS:$SERVER_PORT to reach your instance!" | `which mail` -s "Server $INSTANCE_ID started up!" -a env.sh $SERVER_STARTUP_NOTIFY
|
||||
else
|
||||
echo "OK" | `which mail` -s "Server $INSTANCE_ID started up!" -a env.sh $SERVER_STARTUP_NOTIFY
|
||||
fi
|
||||
fi
|
||||
elif [[ $PARAM == "debug" ]]; then
|
||||
echo "Starting remote debugging session on port 8000"
|
||||
echo "Starting remote debugging session on port 8000 - make sure this port is open"
|
||||
$JAVA_BINARY -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=y -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir=`pwd`/tmp -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -console -configuration ./ -clean
|
||||
elif [[ $PARAM == "fg" ]]; then
|
||||
$JAVA_BINARY -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir=`pwd`/tmp -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -console -configuration ./ -clean
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
TELNET_ACTIVE=`netstat -tlnp 2>/dev/null | grep ":$TELNET_PORT"`
|
||||
if [[ $TELNET_PORT == "" ]] || [[ $TELNET_ACTIVE == "" ]]; then
|
||||
echo "Could not find server on telnet port $TELNET_PORT. Perhaps server is not running?"
|
||||
if [[ $SERVER_STARTUP_NOTIFY != "" ]]; then
|
||||
echo "Stopped" | `which mail` -s "Server $SERVER_NAME could not be stopped!" $SERVER_STARTUP_NOTIFY
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
|
||||
@@ -12,3 +15,6 @@ NC_CMD="nc -t 127.0.0.1 $TELNET_PORT"
|
||||
echo -n exit | $NC_CMD > /dev/null
|
||||
|
||||
echo "Stopped server $SERVER_NAME"
|
||||
if [[ $SERVER_STARTUP_NOTIFY != "" ]]; then
|
||||
echo "OK" | `which mail` -s "Server $SERVER_NAME stopped successfully!" $SERVER_STARTUP_NOTIFY
|
||||
fi
|
||||
@@ -3,29 +3,25 @@
|
||||
The following screenshots will help you creating a new Amazon application instance. An application instance is the container for exactly one Java application server. Each instance is configured using so called "user data". This configuration will then be read by the java server.
|
||||
|
||||
## AMI Selection
|
||||
In the "Classic Wizard" select "My AMIs"
|
||||
In the "Classic Wizard" select "My AMIs" and then select "Sailing Analytics Java Server"
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance1.JPG" width="70%" height="70%"/>
|
||||
|
||||
Make sure to select the AMI with the name "App"
|
||||
Then select an instance type that matches what you want - be aware of the fact that t1.micro is not suitable for build process.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance2.JPG" width="70%" height="70%"/>
|
||||
|
||||
Select a subnet that matches the one of the database server
|
||||
Select a subnet that matches the one of the database server (in most cases this will be eu-west-1c). Leave other options untouched but scroll down to get to the "Advanced Options". There fill the user data field.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance3.JPG" width="70%" height="70%"/>
|
||||
|
||||
Select the correct instance type. Micro also works if you don't want to put that much load on your server.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance4.JPG" width="70%" height="70%"/>
|
||||
|
||||
Leave Kernel and RAM disk to Default. Then put the configuration for this server into the text area labeled "User Data". This configuration should at least contain `MONGODB_*` and `REPLICATION_*` parameters. Here one example:
|
||||
|
||||
<pre>
|
||||
BUILD_BEFORE_START=True
|
||||
BUILD_FROM=master
|
||||
RUN_TESTS=False
|
||||
SERVER_STARTUP-NOTIFY=simon.marcel.pamies@sap.com
|
||||
BUILD_COMPLETE_NOTIFY=simon.marcel.pamies@sap.com
|
||||
SERVER_NAME=LIVE1
|
||||
MEMORY=1024m
|
||||
REPLICATION_HOST=172.31.25.253
|
||||
@@ -40,36 +36,23 @@ REPLICATE_MASTER_SERVLET_HOST=
|
||||
REPLICATE_MASTER_SERVLET_PORT=
|
||||
REPLICATE_MASTER_QUEUE_HOST=
|
||||
REPLICATE_MASTER_QUEUE_PORT=
|
||||
SERVER_STARTUP_NOTIFY=
|
||||
</pre>
|
||||
|
||||
It does not really matter which SERVER_PORTS you use because there is only one app per instance. But this makes it easier to configure instances for Apache, a Load Balancer or other uses. If you want to create a cluster that is self-replicating and has a load balancer in front of it then make sure that all your instances are running on the same port.
|
||||
It does not really matter which SERVER_PORT you use because there is only one app per instance. But this makes it easier to configure instances for Apache, a Load Balancer or other uses. If you want to create a cluster that is self-replicating and has a load balancer in front of it then make sure that all your instances are running on the same port!
|
||||
|
||||
Provide your instance with an useful name.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance5.JPG" width="70%" height="70%"/>
|
||||
|
||||
Use a new interface for your Network. Do not change any other field.
|
||||
Make absolutely sure to select the right Security Group. If you do not select the group "Sailing Analytics App" your server won't be able to access any database.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance6.JPG" width="70%" height="70%"/>
|
||||
|
||||
Now make sure to click on the "Edit" button
|
||||
Configure the key. Make sure to always use the "Administrator" key.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance7.JPG" width="70%" height="70%"/>
|
||||
|
||||
In order to select "Delete on Termination" for your root volume
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance8.JPG" width="70%" height="70%"/>
|
||||
|
||||
Then give your instance a meaningful name by inserting a value for the tag "Name"
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance9.JPG" width="70%" height="70%"/>
|
||||
|
||||
Use the existing "Administrator" Key. Do NOT generate your own key - this won't work. In order to access instances you should've got two private keys. If not then contact one of the administrators.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance10.JPG" width="70%" height="70%"/>
|
||||
|
||||
Then select the preconfigured security group "Sailing Analytics App". Do NOT select anything other than that or create your own.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance11.JPG" width="70%" height="70%"/>
|
||||
|
||||
Your instance is now launching. You can create alarms if you want to monitor the state of the application. Be aware that monitoring is costy.
|
||||
|
||||
<img src="/wiki/images/amazon/StartInstance12.JPG" width="70%" height="70%"/>
|
||||
|
||||
@@ -45,47 +45,53 @@ The architecture is divided into logical tiers. These are represented by firewal
|
||||
<td><b>Name</b></td>
|
||||
<td><b>Access Key(s)</b></td>
|
||||
<td><b>Security Group</b></td>
|
||||
<td><b>Open Ports</b></td>
|
||||
<td><b>Services</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Webserver (Elastic IP: 54.229.94.254)</td>
|
||||
<td>Administrator</td>
|
||||
<td>IN: 20, 80, 443, 2010-2015<br/>OUT: ALL</td>
|
||||
<td>Webserver</td>
|
||||
<td>Apache, GIT, Piwik, Bugzilla</td>
|
||||
<td>Apache, GIT, Piwik, Bugzilla, Wiki</td>
|
||||
<td>This tier holds one instance that has one public Elastic IP associated. This instance manages all domains and subdomains associated with this project. It also contains the public GIT repository.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DB & Messaging</td>
|
||||
<td>Administrator</td>
|
||||
<td>IN: 22, 5672, 10200-10210, 27017<br/>OUT: ALL</td>
|
||||
<td>Database and Messaging</td>
|
||||
<td>MongoDB, MySQL</td>
|
||||
<td>MongoDB, MySQL, RabbitMQ</td>
|
||||
<td>All databases needed by either the Analytics applications or tools like Piwik and Bugzilla are managed by this instance.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Archive</td>
|
||||
<td>Administrator, Sailing User</td>
|
||||
<td>IN: 22, 2010-2015, 8880-8899<br/>OUT: ALL</td>
|
||||
<td>Sailing Analytics App</td>
|
||||
<td>Java App</td>
|
||||
<td>Instance handling the access to all historical races.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Build and Test</td>
|
||||
<td>Administrator, Sailing User</td>
|
||||
<td>Sailing Analytics App</td>
|
||||
<td>X11,Firefox,Hudson</td>
|
||||
<td>Instance that can be used to run tests</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## HowTo
|
||||
|
||||
### Create a new Analytics application instance
|
||||
### Create a new Analytics application instance ready for production
|
||||
|
||||
Create a new Analytics instance as described in detail here [[wiki/amazon-ec2-create-new-app-instance]]. You should use a configuration like the following. If you want to bring the code to a defined level then make sure to specify the BUILD-FROM and BUILD-COMPLETE_NOTIFY variables. If you leave them empty the instance will start using a very old build.
|
||||
Create a new Analytics instance as described in detail here [[wiki/amazon-ec2-create-new-app-instance]]. You should use a configuration like the following. If you want to bring the code to a defined level then make sure to specify the BUILD_FROM and BUILD_COMPLETE_NOTIFY variables. If you leave them empty the instance will start using a very old build.
|
||||
|
||||
Attention: You can not start the building process on t1.micro instances having less than 1.5 GB of RAM!
|
||||
|
||||
<pre>
|
||||
BUILD_BEFORE_START=True
|
||||
BUILD_FROM=master
|
||||
RUN_TESTS=False
|
||||
SERVER_STARTUP_NOTIFY=simon.marcel.pamies@sap.com
|
||||
COMPILE_GWT=True
|
||||
BUILD_COMPLETE_NOTIFY=simon.marcel.pamies@sap.com
|
||||
SERVER_NAME=LIVE1
|
||||
MEMORY=1024m
|
||||
REPLICATION_HOST=172.31.25.253
|
||||
@@ -100,15 +106,53 @@ REPLICATE_MASTER_SERVLET_HOST=
|
||||
REPLICATE_MASTER_SERVLET_PORT=
|
||||
REPLICATE_MASTER_QUEUE_HOST=
|
||||
REPLICATE_MASTER_QUEUE_PORT=
|
||||
SERVER_STARTUP_NOTIFY=
|
||||
</pre>
|
||||
|
||||
After your instance has been started (and build and tests are through) it will be publicly reachable if you chose a port between 8090 and 8099. If you filled the SERVER-STARTUP-NOTIFY field then you will get an email once the server has been started.
|
||||
After your instance has been started (and build and tests are through) it will be publicly reachable if you chose a port between 8090 and 8099. If you filled the BUILD_COMPLETE_NOTIFY field then you will get an email once the server has been built. You can also add your email address to the field SERVER_STARTUP_NOTIFY to get an email whenever the server has been started.
|
||||
|
||||
You can now access this instance by either using the Administrator key (for root User) or the Sailing User key (for user sailing):
|
||||
|
||||
<pre>
|
||||
ssh -i .ssh/Administrator.pem root@ec2-54-246-247-194.eu-west-1.compute.amazonaws.com
|
||||
</pre>
|
||||
|
||||
or
|
||||
|
||||
<pre>
|
||||
ssh -i .ssh/SailingUser.pem sailing@ec2-54-246-247-194.eu-west-1.compute.amazonaws.com
|
||||
</pre>
|
||||
|
||||
If you want to connect your instance to a subdomain then log onto the main webserver with the Administrator key as root, open the file `/etc/httpd/conf.d/001-events.conf` and put something like this there. As you can see you have to specify the IP address and the port the java server is running on. Make sure to always use the internal IP.
|
||||
|
||||
<pre>
|
||||
Use Spectator idm.sapsailing.com "505 IDM 2013" 172.31.22.12 8888
|
||||
</pre>
|
||||
|
||||
### Testing code on a server
|
||||
|
||||
Starting a test is as easy as starting up a new instance. Just make sure that you fill the field RUN_TESTS and set it to `True`. Also set the field BUILD_FROM to a gitspec that matches the code branch that you want to test. After tests has been run and the server has been started you will get an email giving you all the details. You can then access your instance or simply shut it down.
|
||||
|
||||
### Setup replicated instances with ELB
|
||||
|
||||
The main concept behind ELB is that there is one instance that you configure in the "Load Balancers" tab that serves as the main entry point for all requests going to your application. This instance can be told to pass through requests from one port to another. In order to make this ELB instance aware of the Analytics EC2 Instances it should balance over you need to add all instances that should be part of the setup to the ELB instance.
|
||||
|
||||
A closer look reveals that an ELB instance consists itself of many other invisible instances. These are behind a DNS round robin configuration that redirects each incoming request to one of these instances. These invisible instances then decide upon the rules you've created how and where to distribute this request to one of the associated instances.
|
||||
|
||||
### Access build server and tests
|
||||
Here are the steps to create a load balanced setup:
|
||||
|
||||
- Create a master instance holding all data
|
||||
- Create `n` instances that are configured to connect to the master server
|
||||
- Create a load balancer that redirects everything from port 80 to let's say port 8888.
|
||||
- Associate all your instances
|
||||
- Connect your domain with the IP of the load balancer. It could be a good idea to use an Elastic IP that always stays the same for the domain and associate it with your load balancer. That way you can also easily switch between a load balancer and a single instance setup.
|
||||
|
||||
Two things are still needed before this setup can be executed:
|
||||
|
||||
- Make it possible to configure instances that way that they automatically connect to a master upon start
|
||||
- Check what happens if the ELB acts as a transparent proxy not revealing the underlying instance name and address (should be)
|
||||
|
||||
Amazon ELB is designed to handle unlimited concurrent requests per second with “gradually increasing” load pattern (although it's initial capacity is described to reach 20k requests/secs). It is not designed to handle heavy sudden spike of load or flash traffic because of it's internal structure where it needs to fire up more instances when load increases. ELB's can be pre-warmed though by writing to the AWS Support Team.
|
||||
|
||||
### Access MongoDB database
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 531 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 410 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 397 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 256 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 432 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 414 KiB |
@@ -0,0 +1,21 @@
|
||||
# ORC/IRC support
|
||||
|
||||
## Rationale
|
||||
|
||||
## Purpose
|
||||
|
||||
Providing...
|
||||
|
||||
## Features
|
||||
|
||||
* Support for different handicap scoring systems
|
||||
* Time On Time
|
||||
* Time On Distance
|
||||
* Performance Curve
|
||||
* Performance Line
|
||||
|
||||
## Synergies
|
||||
|
||||
|
||||
## Risks
|
||||
|
||||
@@ -148,4 +148,18 @@ Competitor c = competitorDeserializer.deserialize(json);
|
||||
|
||||
3. Whenever you add a Domain Object to an instance, it somehow has to be replicated to the other instances. To do so, create an Operation which you can then `apply()` to the `RacingEventService`, which will then replicate it to other intsances (the operations are basically commands as in the Command pattern, with the added difficulty of operational transformation to provide a uniform final state when operations are applied in different orders on different instances). Internally, the apply-mechanism writes to an `ObjectOutputStream`, which on the other side is evaluated by an `ObjectInputStreamResolvingAgainstDomainFactory`. For this reason, all objects implementing the `IsManagedBySharedDomainFactory` interface are resolved against the domain factory via their `resolve()` implementation. This removes the chance of duplicate instances representing the same actual object.
|
||||
|
||||
4. Also, whenever a replica (slave) instance registers with the master instance, it is provided with the current state of the master as an initial load. To do so, the master instance exports its state via the `serializeForInitialReplication()` method in the `RacintEventServiceImpl`, while the replica recieves the object stream output by the master via the `initiallyFillFrom()` method. Again, an `ObjectInputStreamResolvingAgainstDomainFactory` is used.
|
||||
4. Also, whenever a replica (slave) instance registers with the master instance, it is provided with the current state of the master as an initial load. To do so, the master instance exports its state via the `serializeForInitialReplication()` method in the `RacintEventServiceImpl`, while the replica recieves the object stream output by the master via the `initiallyFillFrom()` method. Again, an `ObjectInputStreamResolvingAgainstDomainFactory` is used.
|
||||
|
||||
## Import Another Year of Magnetic Declination Values
|
||||
|
||||
Under java/com.sap.sailing.declination/resources we store magnetic declination values, using one file per year. The resolution at which we usually store those is one degree of latitude and longitude, each. When for a year those values aren't found in a file, an online request is performed to the [NOAA Service](http://www.ngdc.noaa.gov/geomag-web/) which can be time and bandwidth consuming. Therefore, it is a good idea to keep a file with cached declination values around for the current year.
|
||||
|
||||
To produce such a file, use the `main(...)` method of class `com.sap.sailing.declination.impl.DeclinationStore`. There are pre-defined launch configurations in place in the com.sap.sailing.declination bundle project. Adjust the from/to year parameters for the current year. The process usually takes several hours to complete at a one-degree resolution. Don't forget to commit the resulting resources/declination-<year> file to git.
|
||||
|
||||
Experience has shown that sometimes the SAP HTTP proxy doesn't properly resolve the NOAA service. In those cases, it is more convenient to run the process from either sapsailing.com or stg.sailtracks.de, using something like following command from a server's plugins/ directory after creating the resources/ subdirectory:
|
||||
|
||||
`java -cp com.sap.sailing.domain_*.jar:com.sap.sailing.domain.common_*.jar:com.sap.sailing.declination_*.jar:com.sap.sailing.domain.shared.android_*.jar com.sap.sailing.declination.impl.DeclinationStore 2014 2014 1`
|
||||
|
||||
Run this inside a tmux window to be sure that logging off does not interrupt the process. After the process completes, copy the resulting declination-<year> file to your git workspace to `java/com.sap.sailing.declination/resources` and commit.
|
||||
|
||||
There is also a script java/target/importdeclination that automates these steps.
|
||||