From e3c6ae9751ab74f859e29b24e7da19e193373248 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Mon, 5 Aug 2013 16:34:47 +0200 Subject: [PATCH 001/227] Updated onboarding (markdown) --- wiki/onboarding.md | 205 +++++++++++++++++++++++---------------------- 1 file changed, 103 insertions(+), 102 deletions(-) diff --git a/wiki/onboarding.md b/wiki/onboarding.md index 647439656f2..7fccbf35bc0 100644 --- a/wiki/onboarding.md +++ b/wiki/onboarding.md @@ -1,102 +1,103 @@ -# OnBoarding Information - -This document describes the onboarding process for a new team member (developer) - -### Race Analysis Development Setup - -#### Installations - -1. Eclipse (e.g. Eclipse Classic 4.2.1 (Juno)), http://www.eclipse.org -2. Eclipse Extensions - * Install Eclipse GWT should be version 2.5 (https://developers.google.com/eclipse/docs/download) -3. Git (e.g. msysGit for Windows v1.7.10), http://git-scm.com -4. MongoDB (e.g. Production Release 2.0.4), download: http://www.mongodb.org/ -5. RabbitMQ, download from http://www.rabbitmq.com/. Requires Erlang to be installed. RabbitMQ installer will assist in installing Erlang. -6. JDK 1.6 (Java SE 6), http://jdk6.java.net (for GWT) -7. JDK 1.7 (Java SE 7), http://jdk7.java.net -8. Maven 3, http://maven.apache.org - -#### Further optional but recommended installations - -1. Cygwin, http://www.cygwin.com/ -2. Eclipse Mylyn Bugzilla extension -3. kdiff3 (git tool) -4. Firebug (javascript & .css debugging) - -#### Accounts - -1. Git Account -- Register yourself as a Git user in the SAP-Git under: https://git.wdf.sap.corp:8080/ -- Ask the Git administrator (Axel Uhl) to get on the list of enabled committers - -2. Bugzilla -- Ask the Bugzilla administrator (Frank Mittag, Axel Uhl) to create a bugzilla account for you. -- Bugzilla url: http://sapcoe-app01.pironet-ndh.com/bugzilla/ - -3. Race Analysis user -- Add yourself as an user to the Race Analysis suite by adding a Jetty user in the file - java\target\configuration\jetty\etc\realm.properties - -#### Steps to build and run the Race Analysis Suite - -1. Get the content of the git repository -- Clone the repository to your local file system from `ssh://[SAP-User]@git.wdf.sap.corp:29418/SAPSail/sapsailingcapture.git` or `ssh://[user]@sapsailing.com/home/trac/git` - -2. Check out the 'master' branch from the git repository. The 'master' branch is the main development branch. Please check that you start your work on this branch. - -3. Setup and configure Eclipse - - Make absolutely sure to import CodeFormatter.xml (from $GIT_HOME/java) into your Eclipse preferences (Preferences->Java->Code Style->Fortmatter) - - Install the Eclipse GWT-Plugin (now called Google Plugin for Eclipse, you need the Gogle WebToolkit SDK from the same update site, too) - - Install Eclipse eGit (optional) - - Check that JDK 1.7 is available and has been set for compilation in Eclipse - - Check that the both JDKs are available (Windows->Preferences->Java->Installed JREs) - - Check that JDK 1.6 has been matched to JavaSE-1.6 and that JDK 1.7 has been matched to JavaSE-1.7 (...>Installed JREs>Execution Environments) - - It is also possible to match the SAPJVM 6 or 7 to the JavaSE-1.6 (for profiling purposes) - - Import all Race Analysis projects from the /java(!!!) subdirectory of the git main folder - - Set the Eclipse target platform to race-analysis-p2-ide-local.target (located in com.sap.sailing.targetplatform/definitions) - - Wait until the target platform has been resolved completely - - In the project com.sap.sailing.gwt.ui create a new subfolder "classes" in the folder WEB-INF - - Rebuild all projects - -4. Run the Race Analysis Suite - - Start the MongoDB - - Start the appropriate Eclipse launch configuration (e.g. 'Sailing Server (Proxy)') - - Start the GWT UI - -5. Within the Race Analysis Suite - - For TracTrac Events: (Date 27.11.2012) Use Live URI tcp://10.18.22.156:4412, Stored URI tcp://10.18.22.156:4413, JSON URL http://germanmaster.traclive.dk/events/event_20120905_erEuropean/jsonservice.php - - Press List Races - -#### Maven Setup -Copy the settings.xml from the top-level git folder to your ~/.m2 directory and adjust the proxy settings accordingly. Make sure the mvn executable you installed above is in your path. Open a shell (preferrably a git bash or a cygwin bash), cd to the java/ subfolder of the git workspace and issue "mvn -fae clean install". This should build the software and run all the tests. If you want to avoid the tests being executed, run "mvn -Dmaven.test.skip=true -fae clean install". If you want to make sure the GWT compiler really re-builds all artifacts, remove all java/com.sap.sailing.gwt.ui/com.sap.sailing.gwt.ui.* directories, then re-build. - -#### Further hints -- Configure Eclipse to use Chrome or Firefox as the default browser -- Install the GWT Browser Plugin (Chrome or Firefox) for the GWT Development mode - -#### Additional steps required for Android projects - -To ensure that all components of the Analysis Suite are working, you should also import all Android projects into your workspace. There are some additional requirements to enable the build process of these projects. - -1. Add the Android Development Tools (ADT) plugin to your Eclipse IDE - - In Eclipse click Help -> Install New Software -> Add and enter https://dl-ssl.google.com/android/eclipse/ - - Select the Developer Tools and install - - After restarting Eclipse the "Welcome to Android Development" window should help you with installing the Android SDK - - It is also possible to download the Android SDK separately from http://developer.android.com/sdk/index.html ("Use an existing IDE") -2. Setup the Android SDK - - In Eclipse press Window -> Android SDK Manager - - Ensure that everything of "Tools" is installed - - Install everything of "Android 3.2 API 13" - - Install "Android Support Library" (Extras), "Google Play Services" (Extras) and "Google USB Driver" (Extras) -3. Import the Android projects into your workspace - - Android projects can be found in the /mobile subdirectory - -To deploy an Android project (for example com.sap.sailing.racecommittee.app) to a device -1. Plug-in the device - - Development mode must be enabled on the device - - For certain device/OS combinations additional device drivers are needed - - You can check if the device is detected correctly by checking the "Devices" tab of the "DDMS" Eclipse perspective. -2. Start a run configuration of the project -3. Select your attached device in the device selection screen -4. The app should be started after deployment - +# OnBoarding Information + +This document describes the onboarding process for a new team member (developer) + +### Race Analysis Development Setup + +#### Installations + +1. Eclipse (e.g. Eclipse Classic 4.2.1 (Juno)), http://www.eclipse.org +2. Eclipse Extensions + * Install Eclipse GWT should be version 2.5 (https://developers.google.com/eclipse/docs/download) +3. Git (e.g. msysGit for Windows v1.7.10), http://git-scm.com +4. MongoDB (e.g. Production Release 2.0.4), download: http://www.mongodb.org/ +5. RabbitMQ, download from http://www.rabbitmq.com/. Requires Erlang to be installed. RabbitMQ installer will assist in installing Erlang. +6. JDK 1.6 (Java SE 6), http://jdk6.java.net (for GWT) +7. JDK 1.7 (Java SE 7), http://jdk7.java.net +8. Maven 3, http://maven.apache.org + +#### Further optional but recommended installations + +1. Cygwin, http://www.cygwin.com/ +2. Eclipse Mylyn Bugzilla extension +3. kdiff3 (git tool) +4. Firebug (javascript & .css debugging) + +#### Accounts + +1. Git Account +- Register yourself as a Git user in the SAP-Git under: https://git.wdf.sap.corp:8080/ +- Ask the Git administrator (Axel Uhl) to get on the list of enabled committers + +2. Bugzilla +- Ask the Bugzilla administrator (Frank Mittag, Axel Uhl) to create a bugzilla account for you. +- Bugzilla url: http://sapcoe-app01.pironet-ndh.com/bugzilla/ + +3. Race Analysis user +- Add yourself as an user to the Race Analysis suite by adding a Jetty user in the file + java\target\configuration\jetty\etc\realm.properties + +#### Steps to build and run the Race Analysis Suite + +1. Get the content of the git repository +- Clone the repository to your local file system from `ssh://[SAP-User]@git.wdf.sap.corp:29418/SAPSail/sapsailingcapture.git` or `ssh://[user]@sapsailing.com/home/trac/git` + +2. Check out the 'master' branch from the git repository. The 'master' branch is the main development branch. Please check that you start your work on this branch. + +3. Setup and configure Eclipse + - Make absolutely sure to import CodeFormatter.xml (from $GIT_HOME/java) into your Eclipse preferences (Preferences->Java->Code Style->Fortmatter) + - Install the Eclipse GWT-Plugin (now called Google Plugin for Eclipse, you need the Gogle WebToolkit SDK from the same update site, too) + - Install Eclipse eGit (optional) + - Check that JDK 1.7 is available and has been set for compilation in Eclipse + - Check that the both JDKs are available (Windows->Preferences->Java->Installed JREs) + - Check that JDK 1.6 has been matched to JavaSE-1.6 and that JDK 1.7 has been matched to JavaSE-1.7 (...>Installed JREs>Execution Environments) + - It is also possible to match the SAPJVM 6 or 7 to the JavaSE-1.6 (for profiling purposes) + - Import all Race Analysis projects from the /java(!!!) subdirectory of the git main folder + - Set the Eclipse target platform to race-analysis-p2-ide-local.target (located in com.sap.sailing.targetplatform/definitions) + - Wait until the target platform has been resolved completely + - In the project com.sap.sailing.gwt.ui create a new subfolder "classes" in the folder WEB-INF + - Rebuild all projects + +4. Run the Race Analysis Suite + - Start the MongoDB + - Start the appropriate Eclipse launch configuration (e.g. 'Sailing Server (Proxy)') + - Start the GWT UI + +5. Within the Race Analysis Suite + - For TracTrac Events: (Date 27.11.2012) Use Live URI tcp://10.18.22.156:4412, Stored URI tcp://10.18.22.156:4413, JSON URL http://germanmaster.traclive.dk/events/event_20120905_erEuropean/jsonservice.php + - Press List Races + +#### Maven Setup +Copy the settings.xml from the top-level git folder to your ~/.m2 directory and adjust the proxy settings accordingly. Make sure the mvn executable you installed above is in your path. Open a shell (preferrably a git bash or a cygwin bash), cd to the java/ subfolder of the git workspace and issue "mvn -fae clean install". This should build the software and run all the tests. If you want to avoid the tests being executed, run "mvn -Dmaven.test.skip=true -fae clean install". If you want to make sure the GWT compiler really re-builds all artifacts, remove all java/com.sap.sailing.gwt.ui/com.sap.sailing.gwt.ui.* directories, then re-build. + +#### Further hints +- Configure Eclipse to use Chrome or Firefox as the default browser +- Install the GWT Browser Plugin (Chrome or Firefox) for the GWT Development mode + +#### Additional steps required for Android projects + +To ensure that all components of the Analysis Suite are working, you should also import all Android projects into your workspace. There are some additional requirements to enable the build process of these projects. + +1. Add the Android Development Tools (ADT) plugin to your Eclipse IDE + - In Eclipse click Help -> Install New Software -> Add and enter https://dl-ssl.google.com/android/eclipse/ + - Select the Developer Tools and install + - After restarting Eclipse the "Welcome to Android Development" window should help you with installing the Android SDK + - It is also possible to download the Android SDK separately from http://developer.android.com/sdk/index.html ("Use an existing IDE") +2. Setup the Android SDK + - In Eclipse press Window -> Android SDK Manager + - Ensure that everything of "Tools" is installed + - Install everything of "Android 3.2 API 13" + - Install "Android Support Library" (Extras), "Google Play Services" (Extras) and "Google USB Driver" (Extras) +3. Import the Android projects into your workspace + - Android projects can be found in the /mobile subdirectory + +To deploy an Android project (for example com.sap.sailing.racecommittee.app) to a device + +1. Plug-in the device + - Development mode must be enabled on the device + - For certain device/OS combinations additional device drivers are needed + - You can check if the device is detected correctly by checking the "Devices" tab of the "DDMS" Eclipse perspective. +2. Start a run configuration of the project +3. Select your attached device in the device selection screen +4. The app should be started after deployment + From 31dbaaa18fc7a9c15292f5360c54dc3422b0a709 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Mon, 5 Aug 2013 16:39:53 +0200 Subject: [PATCH 002/227] Updated mobile development (markdown) --- wiki/mobile-development.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wiki/mobile-development.md b/wiki/mobile-development.md index 71862ffa82e..f23c8ed98ba 100644 --- a/wiki/mobile-development.md +++ b/wiki/mobile-development.md @@ -1,5 +1,7 @@ # Mobile Development +See [[OnBoarding|wiki/onboarding]] how to set up your build environment for mobile development. + The native Android projects are in the mobile/ folder in git which is next to the java/ folder. To build them successfully, you need to install the Android SDK which is available [here](http://developer.android.com/sdk/index.html). Also, you need to use the Eclipse update site https://dl-ssl.google.com/android/eclipse and install the Eclipse ADT plugins. Currently (2013-07-18), the Race Committee App uses the Google APIs Version 13 (Android 3.2) which you need to install through the Android SDK Manager (see Eclipse toolbar after installing the Eclipse ADT plugin). In the Android Virtual Device manager which can also be found in the Eclipse toolbar you can configure an emulated device. One successful approach was using a 10.1" WXGA (Tablet) device in the emulator configuration and choose "Google APIs (Google Inc.) - API Level 13" as the target. From 68881a52d28142799f5ce9c2ff11148b55c8bfc1 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Mon, 5 Aug 2013 16:42:27 +0200 Subject: [PATCH 003/227] Updated mobile development (markdown) --- wiki/mobile-development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/mobile-development.md b/wiki/mobile-development.md index f23c8ed98ba..096c3b4e99c 100644 --- a/wiki/mobile-development.md +++ b/wiki/mobile-development.md @@ -1,6 +1,6 @@ # Mobile Development -See [[OnBoarding|wiki/onboarding]] how to set up your build environment for mobile development. +See [[On Boarding|wiki/onboarding]] how to set up your build environment for mobile development. The native Android projects are in the mobile/ folder in git which is next to the java/ folder. To build them successfully, you need to install the Android SDK which is available [here](http://developer.android.com/sdk/index.html). Also, you need to use the Eclipse update site https://dl-ssl.google.com/android/eclipse and install the Eclipse ADT plugins. From d71e52ce214d1a197eb8fa4e98cf26a23aeebf0d Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 5 Aug 2013 16:59:55 +0200 Subject: [PATCH 004/227] Updated onboarding (markdown) --- wiki/onboarding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/onboarding.md b/wiki/onboarding.md index 7fccbf35bc0..5edf46c101e 100644 --- a/wiki/onboarding.md +++ b/wiki/onboarding.md @@ -31,7 +31,7 @@ This document describes the onboarding process for a new team member (developer) 2. Bugzilla - Ask the Bugzilla administrator (Frank Mittag, Axel Uhl) to create a bugzilla account for you. -- Bugzilla url: http://sapcoe-app01.pironet-ndh.com/bugzilla/ +- Bugzilla url: http://sapsailing.com/bugzilla/ 3. Race Analysis user - Add yourself as an user to the Race Analysis suite by adding a Jetty user in the file From e9c6b894118d04e4178079328382a8709de9c2da Mon Sep 17 00:00:00 2001 From: Potsdam Date: Mon, 5 Aug 2013 17:14:43 +0200 Subject: [PATCH 005/227] Updated mobile development (markdown) --- wiki/mobile-development.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/wiki/mobile-development.md b/wiki/mobile-development.md index 096c3b4e99c..36b72a980ce 100644 --- a/wiki/mobile-development.md +++ b/wiki/mobile-development.md @@ -2,10 +2,17 @@ See [[On Boarding|wiki/onboarding]] how to set up your build environment for mobile development. -The native Android projects are in the mobile/ folder in git which is next to the java/ folder. To build them successfully, you need to install the Android SDK which is available [here](http://developer.android.com/sdk/index.html). Also, you need to use the Eclipse update site https://dl-ssl.google.com/android/eclipse and install the Eclipse ADT plugins. +Besides running the application on a plugged-in device there are multiple options for using an emulator: -Currently (2013-07-18), the Race Committee App uses the Google APIs Version 13 (Android 3.2) which you need to install through the Android SDK Manager (see Eclipse toolbar after installing the Eclipse ADT plugin). In the Android Virtual Device manager which can also be found in the Eclipse toolbar you can configure an emulated device. One successful approach was using a 10.1" WXGA (Tablet) device in the emulator configuration and choose "Google APIs (Google Inc.) - API Level 13" as the target. - -After that it should be possible to choose "Debug as --> Android application" in the com.sap.sailing.racecommittee.app project's context menu, then pick the emulator you're previously created. - -If you want to run the app against your locally-running server, go into the Settings and choose http://10.0.2.2:8888 as the JSON URL. See also [here](http://developer.android.com/tools/devices/emulator.html#emulatornetworking) for more details on the emulator's network behavior. \ No newline at end of file +* Android Virtual Device (AVD) + * Default Android emulator + * Comes with the ADT and is well integrated into Eclipse + * In the AVD manager which can be found in the Eclipse toolbar you can configure an emulated device. Create a 10.1" WXGA (Tablet) device in the emulator configuration and choose "Google APIs (Google Inc.) - API Level 13" as the target. + * Use virtual device as described in [[On Boarding|wiki/onboarding]] + * If you want to run the app against your locally-running server, go into the Settings and choose http://10.0.2.2:8888 as the JSON URL. See also [here](http://developer.android.com/tools/devices/emulator.html#emulatornetworking) for more details on the emulator's network behavior. +* Genymotion (AndroVM) + * VirtualBox-based Android emulator + * Currently in free beta phase; way faster than AVD; better support for Google Apps (e.g. Maps) and easy access to sensor features (e.g. setting GPS info) + * Register at http://www.genymotion.com/, download and install virtual device "WXGA 10.1 Tablet - 4.1.1 - with Google Apps - API 16 - 1280x800" with 160dpi + * If you want to run the app against your locally-running server, check the IP address of your host machine for the VirtualBox network interface. Use this IP when you are configuring the app. + * Use virtual device as described in [[On Boarding|wiki/onboarding]] \ No newline at end of file From a7f91b8a612d1258963e6b7f06581ca58a001ec2 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Mon, 5 Aug 2013 17:18:51 +0200 Subject: [PATCH 006/227] Updated mobile development (markdown) --- wiki/mobile-development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/mobile-development.md b/wiki/mobile-development.md index 36b72a980ce..ee79996d2f0 100644 --- a/wiki/mobile-development.md +++ b/wiki/mobile-development.md @@ -1,6 +1,6 @@ # Mobile Development -See [[On Boarding|wiki/onboarding]] how to set up your build environment for mobile development. +See [On Boarding](wiki/onboarding#Additional-steps-required-for-Android-projects) how to set up your build environment for mobile development. Besides running the application on a plugged-in device there are multiple options for using an emulator: From 224ab09a07f12eccea4948c4d2dcceb95c25344b Mon Sep 17 00:00:00 2001 From: Potsdam Date: Mon, 5 Aug 2013 17:19:08 +0200 Subject: [PATCH 007/227] Updated mobile development (markdown) --- wiki/mobile-development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/mobile-development.md b/wiki/mobile-development.md index ee79996d2f0..b5241218a63 100644 --- a/wiki/mobile-development.md +++ b/wiki/mobile-development.md @@ -1,6 +1,6 @@ # Mobile Development -See [On Boarding](wiki/onboarding#Additional-steps-required-for-Android-projects) how to set up your build environment for mobile development. +See [On Boarding](onboarding#Additional-steps-required-for-Android-projects) how to set up your build environment for mobile development. Besides running the application on a plugged-in device there are multiple options for using an emulator: From 166ceddfa414a491d0ec8033006b77097580aba9 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Mon, 5 Aug 2013 17:21:00 +0200 Subject: [PATCH 008/227] Updated onboarding (markdown) --- wiki/onboarding.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wiki/onboarding.md b/wiki/onboarding.md index 5edf46c101e..81beaba16ca 100644 --- a/wiki/onboarding.md +++ b/wiki/onboarding.md @@ -91,7 +91,7 @@ To ensure that all components of the Analysis Suite are working, you should also 3. Import the Android projects into your workspace - Android projects can be found in the /mobile subdirectory -To deploy an Android project (for example com.sap.sailing.racecommittee.app) to a device +To deploy an Android project (for example com.sap.sailing.racecommittee.app) to a real device: 1. Plug-in the device - Development mode must be enabled on the device @@ -101,3 +101,4 @@ To deploy an Android project (for example com.sap.sailing.racecommittee.app) to 3. Select your attached device in the device selection screen 4. The app should be started after deployment +See [Mobile Development](wiki/mobile-development) for further options to run the applications using emulators. \ No newline at end of file From f403dee79efd1bf710928b47a6522b6e1dbd9cc0 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Mon, 5 Aug 2013 17:21:26 +0200 Subject: [PATCH 009/227] Updated onboarding (markdown) --- wiki/onboarding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/onboarding.md b/wiki/onboarding.md index 81beaba16ca..2c727e64e75 100644 --- a/wiki/onboarding.md +++ b/wiki/onboarding.md @@ -101,4 +101,4 @@ To deploy an Android project (for example com.sap.sailing.racecommittee.app) to 3. Select your attached device in the device selection screen 4. The app should be started after deployment -See [Mobile Development](wiki/mobile-development) for further options to run the applications using emulators. \ No newline at end of file +See [Mobile Development](mobile-development) for further options to run the applications including emulators. \ No newline at end of file From 1036181e18e76b25e5b802c43550a4d9c8fff0b0 Mon Sep 17 00:00:00 2001 From: Jan Bross Date: Wed, 7 Aug 2013 09:05:43 +0200 Subject: [PATCH 010/227] Updated smartphone tracking (markdown) --- wiki/smartphone-tracking.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wiki/smartphone-tracking.md b/wiki/smartphone-tracking.md index dc0d4583057..5a78dd2a120 100644 --- a/wiki/smartphone-tracking.md +++ b/wiki/smartphone-tracking.md @@ -191,6 +191,8 @@ Includes a `Competitor` as well a `SmartphoneIdentifier`. On the one hand, every ### RaceLogPreRacePhaseEndedEvent This does not include any additional data, and merely indicates that the race can be transformed from its pre-race definition state (e.g. waiting for competitors to register, waiting for boat class, waiting for course definition) to an actual race, where no additional competitors can be added, the boat class is fixes, and tracking may begin. This event is picked up by the `RaceLogRaceTracker`, which then creates the actual tracked race from the data in the RaceLog. For successful creation, at least one competitor has to be registered, and a course must have been set through a `RaceLogCourseDefinitionChangedEvent`. +##Tracking App Use Cases +![Use Cases](http://i.imagebanana.com/img/bda86luu/Use_Cases.jpg) ##Tracking App Architecture From 11d4be85aff0427c847b78a6fb516ecfed7dd801 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 7 Aug 2013 16:24:35 +0200 Subject: [PATCH 011/227] Updated home (markdown) --- home.md | 1 + 1 file changed, 1 insertion(+) diff --git a/home.md b/home.md index ab68bb635dc..aefe102d7fc 100644 --- a/home.md +++ b/home.md @@ -18,6 +18,7 @@ Like businesses, sailors need the latest information to make strategic decisions * Information for Developers * [[Cook Book|wiki/cook-book]] * [[OnBoarding Information|wiki/onboarding]] + * [[UI Tests with Selneium|wiki/selenium-ui-tests]] * [[Typical Development Scenarios|wiki/typical-development-scenarios]] * [[Server Replication|wiki/server-replication]] * [[Configure Races on Server|wiki/typical-development-scenarios]] From 8fca225fc7eb13b0fe507af1004886fc041799bc Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 7 Aug 2013 16:24:53 +0200 Subject: [PATCH 012/227] Updated home (markdown) --- home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home.md b/home.md index aefe102d7fc..e6ee689ada0 100644 --- a/home.md +++ b/home.md @@ -18,7 +18,7 @@ Like businesses, sailors need the latest information to make strategic decisions * Information for Developers * [[Cook Book|wiki/cook-book]] * [[OnBoarding Information|wiki/onboarding]] - * [[UI Tests with Selneium|wiki/selenium-ui-tests]] + * [[UI Tests with Selenium|wiki/selenium-ui-tests]] * [[Typical Development Scenarios|wiki/typical-development-scenarios]] * [[Server Replication|wiki/server-replication]] * [[Configure Races on Server|wiki/typical-development-scenarios]] From bf93559c699365227d7f05bf529e5a7bb726e685 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 7 Aug 2013 16:25:36 +0200 Subject: [PATCH 013/227] Created selenium ui tests (markdown) --- wiki/selenium-ui-tests.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 wiki/selenium-ui-tests.md diff --git a/wiki/selenium-ui-tests.md b/wiki/selenium-ui-tests.md new file mode 100644 index 00000000000..910d0f8d4e8 --- /dev/null +++ b/wiki/selenium-ui-tests.md @@ -0,0 +1,3 @@ +# UI Tests with Selenium + +TODO to be filled in by Riccardo \ No newline at end of file From 86a2336797a93c8dd284aa42c2b7e4571bae7bf5 Mon Sep 17 00:00:00 2001 From: Jan Bross Date: Thu, 8 Aug 2013 10:46:46 +0200 Subject: [PATCH 014/227] Updated smartphone tracking (markdown) --- wiki/smartphone-tracking.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/wiki/smartphone-tracking.md b/wiki/smartphone-tracking.md index 5a78dd2a120..b43fe6fc949 100644 --- a/wiki/smartphone-tracking.md +++ b/wiki/smartphone-tracking.md @@ -159,9 +159,13 @@ To test the servlets manually, in addition to the unit tests, the chrome plugin **Expects** * POST request body: PingMark as JSON ``` -{"unixtime": 2394820480284, - "nmea" : "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A" - } +{ + "markStringId": "Leeward Mark" + "gpsFix": { + "unixtime": 1375951388465, + "nmea": "$GPRMC,084308,A,41.771311,N,86.933174,E,0.0,0.0,080813,0,W*4D" + }, +} ``` **Returns** From bc1e64a380b02417f567f10fa9cc2d24274561f2 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 8 Aug 2013 14:03:52 +0200 Subject: [PATCH 015/227] Updated home (markdown) --- home.md | 1 + 1 file changed, 1 insertion(+) diff --git a/home.md b/home.md index e6ee689ada0..9f9d46a31ce 100644 --- a/home.md +++ b/home.md @@ -23,6 +23,7 @@ Like businesses, sailors need the latest information to make strategic decisions * [[Server Replication|wiki/server-replication]] * [[Configure Races on Server|wiki/typical-development-scenarios]] * [[Development Environment|wiki/development-environment]] + * [[Working with GWT Locally|wiki/local-gwt]] * [[Mobile Development|wiki/mobile-development]] * General Information * [[Architecture and Infrastructure|wiki/architecture-and-infrastructure]] From 2ae9770025c4fd438a01df8e6c4df9b5e0d42d7d Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 8 Aug 2013 14:07:58 +0200 Subject: [PATCH 016/227] Updated development environment (markdown) --- wiki/development-environment.md | 136 +++++++++++++++++--------------- 1 file changed, 71 insertions(+), 65 deletions(-) diff --git a/wiki/development-environment.md b/wiki/development-environment.md index 6db506b6299..003faac8f00 100644 --- a/wiki/development-environment.md +++ b/wiki/development-environment.md @@ -1,65 +1,71 @@ -# Development Environment - -[[_TOC_]] - -## Git and Our Branches -Our main Git repository lives at ssh://@sapsailing.com/home/trac/git. For those working in the SAP corporate network and therefore unable to access the external sapsailing.com server using SSH, the repository contents are replicated on an hourly basis into ssh://dxxxxxx@git.wdf.sap.corp:29418/SAPSail/sapsailingcapture.git where dxxxxxx obviously is to be replaced by your D- or I- or C-user. You need to have an account at https://git.wdf.sap.corp:8080/ to be able to access this Git repository. - -Small, obvious and non-disruptive developments are usually carried out immediately on our master branch. This branch is configured such that Maven can be used to run the tests inside the SAP corporate network. The master branch is never deployed onto the sapsailing.com server and hence has no corresponding /home/trac/servers/ subdirectory. - -If a change looks reasonably good on the master branch and related JUnit tests or manual UI tests have succeeded locally, it is permissible to merge the master branch into the dev branch and run a central build on sapsailing.com. The dev branch is configured to run the Maven tests with direct Internet access. It can therefore also be used to run the tests locally if connected to the public Internet. - -Ideally, the build should be run including the test cases. If the tests succeed , the branch can be installed and the corresponding server instance can be restarted. The branch can then also be promoted to the next level (dev-->test-->prod1/prod2). Note, that currently re-starting a server instance may require re-loading the races that were previously loaded, particularly for the prod1 and prod2 instances, because several externally-announced URLs point to them. - -We typically promote the changes to the next branch by also merging the current master branch into the next-"higher" branch. This should lead to equivalent results compared to merging the "previous" branch (e.g., dev) into the "next" branch (e.g., test). The branches differ largely in the configurations used for the servers, particularly the port assignments for the Jetty web server, the UDP ports used for listening for Expedition wind messages, and the queue names used for the replication based on RabbitMQ (see also Scale-Out through Replication). - -## Eclipse Setup, Required Plug-Ins -We use Eclipse as our development environment. Using a different IDE would make it hard to re-use the project configurations (.project and .classpath files which are specific to Eclipse) as well as the GWT plug-in which assists in locally compiling and refactoring the GWT code, in particular the RPC code. - -The recommended and tested Eclipse version is currently Indigo (3.7). Colleagues have reported that they succeeded with a Juno (3.8/4.x) set-up as well. - -To get started, install Eclipse with at least PDE, Git, GWT (use http://dl.google.com/eclipse/plugin/3.7 as update site) and JSP editing support enabled. Eclipse Maven support is not recommended as in many cases it has caused trouble with the local Eclipse build. - -## Target Platform -After the Eclipse installation and importing all projects under java/ from Git, it is required to set the target platform in Eclipse (Window --> Preferences --> Plugin Development --> Target Platform). The project com.sap.sailing.targetplatform contains "Race Analysis Target (IDE)" as target platform definition. It uses a number of p2 update sites and defines the OSGi bundles that constitute the target platform for the application. If this is not set in Eclipse, the local build environment assumes that the developer wants to implement Eclipse plug-ins and offers the entire set of Eclipse plug-ins and only those as the target platform which doesn't make any sense for our application. - -Major parts of our target platform are hosted on sapsailing.com as a p2 repository which makes it possible to have only one central target platform configuration used by everyone. The target platform can be re-built, e.g., after adding another bundle to it, using the script in com.sap.sailing.targetplatform/scripts. - -It then needs to be installed again (by using a tool like scp for instance) to the /home/trac/p2-repositories directory from where it is exposed as http://sapcoe-app01.pironet-ndh.com/p2/sailing/ by the Apache web server. After such a change, all developers need to reload the target platform into their Eclipse environment. - -## Maven Build and Tests -We use Maven to build our software and run our JUnit tests. The global setting.xml file to install in everyone's ~/.m2 directory is checked into the top-level Git folder. The checked-in copy assumes the developer is using Maven inside the SAP corporate network. If not, uncomment the tag in the settings.xml file. See also section Git and Our Branches for details on which branch is configured to work in which network setup. - -We have a top-level Maven pom.xml configuration file in the root folder of our Git workspace. It delegates to the pom.xml file in the java/ folder where all the bundle projects are defined. We rely on the Tycho Maven plug-in to build our OSGi bundles, also known as the "manifest-first approach." The key idea is to mainly develop using Eclipse means, including its OSGi manifest editing capabilities, and keep the Maven infrastructure as simple as possible, deriving component dependencies from the OSGi manifests. See the various pom.xml files in the projects to see the project-specific settings. By and large, a pom.xml file for a bundle needs to have the bundle name and version defined (we currently have most bundles at version 1.0.0.qualifier in the manifest or 1.0.0.SNAPSHOT in Maven), and whether the bundle is a test or non-test bundle, expressed as the packaging type which here can be one of eclipse-plugin or ecplise-test-plugin. - -Test plugins automatically have their tests executed during a Maven build unless the command-line option -Dmaven.test.skip=true argument is specified. It is generally a good idea to launch the Maven command using the -fae option which asks Maven to continue until the end, even if errors or failures occurred on the way, failing at the end if any failures occurred. This can save numerous round trips and is useful in case of known and temporarily acceptable test failures. - -The Maven plug-in for the GWT compilation doesn't reliably perform a dependency check. It is therefore recommended to remove all contents of the java/com.sap.sailing.gwt.ui/com.sap.sailing.* folders (basically, all GWT compiler output) before launching the Maven build. A good command line for the Maven build from the java/ subdirectory in your local environment when outside the SAP VPN is this: - - `rm -rf com.sap.sailing.gwt.ui/com.sap.sailing.*; mvn -fae -P debug.without-proxy clean install 2>&1 | tee log` - -Inside the SAP VPN you may want to use a different profile which accounts for the proxies that have to be used: - - `rm -rf com.sap.sailing.gwt.ui/com.sap.sailing.*; mvn -fae -P debug.with-proxy clean install 2>&1 | tee log` - -When building on sapsailing.com you have to explicitly specify the settings.xml file from the git workspace. You also have to make sure the DISPLAY environment variable is set to ":2.0" to send test browsers to a VNC display. Should the GWT build fail because it cannot open enough files, ensure the "ulimit -n" output is at least 4096 to enable the GWT compiler to assemble the resource sets which consist of many files that all need to be opened concurrently. Currently, the maximum value for "ulimit -n" is configured in /etc/security/limits.conf and is set to 16384. This specified the maximum amount to which a user's shell can set this value. The ~trac/.bash_profile contains a "ulimit -n 4096" command, but when running "screen" the shells usually are no login shells. You need to make sure you run ~trac/.bash_profile in the build shell to set the limit of open files to at least 4096. Then issue `rm -rf com.sap.sailing.gwt.ui/com.sap.sailing.*; mvn -fae -s /home/trac/git/settings.xml -P debug.without-proxy clean install 2>&1 | tee log` - -All these build lines also creates a log file with all error messages, just in case the screen buffer is not sufficient to hold all scrolling error messages. - -## Product and Features -The result of the build process is a p2 repository with a product consisting of a number of features. The product configuration is provided by the file raceanalysis.product in the com.sap.sailing.feature.p2build project. In its dependencies it defines the features of which it is built, which currently are com.sap.sailing.feature and com.sap.sailing.feature.runtime, each described in an equal-named bundle. - -The feature specified by com.sap.sailing.feature lists the bundles we develop ourselves as part of the project. The com.sap.sailing.feature.runtime feature lists those 3rd-party bundles from the target platform which are required by the product. - -## External Libraries - -### Highcharts and jQuery -We use the Highcharts library to present graphs to the user. These graphs are used on the RaceBoardPanel and (at the time of writing still under development) the PolarSheetsPanel. In the past, there were difficulties concerning the versions of the three interacting libraries: - -* The GWT Highcharts Wrapper – The source code can be found in our project and it’s slightly modified to match our scenario -* The actual Highcharts Library -* The jQuery Library - -To support polar diagrams we use version 3.5.0 of the wrapper. This version is tested with version 2.3.3 of the Highcharts library. We tried using 2.3.5 but that led to problems when resizing the RaceBoard. - -Highcharts uses the jQuery library. We do know that version 1.4.2 does NOT work with the versions of Highcharts mentioned above. Multiple yAxis are not initialized correctly. We know use version 1.5.2 of this library. +# Development Environment + +[[_TOC_]] + +## Git and Our Branches +Our main Git repository lives at ssh://@sapsailing.com/home/trac/git. For those working in the SAP corporate network and therefore unable to access the external sapsailing.com server using SSH, the repository contents are replicated on an hourly basis into ssh://dxxxxxx@git.wdf.sap.corp:29418/SAPSail/sapsailingcapture.git where dxxxxxx obviously is to be replaced by your D- or I- or C-user. You need to have an account at https://git.wdf.sap.corp:8080/ to be able to access this Git repository. + +Small, obvious and non-disruptive developments are usually carried out immediately on our master branch. This branch is configured such that Maven can be used to run the tests inside the SAP corporate network. The master branch is never deployed onto the sapsailing.com server and hence has no corresponding /home/trac/servers/ subdirectory. + +If a change looks reasonably good on the master branch and related JUnit tests or manual UI tests have succeeded locally, it is permissible to merge the master branch into the dev branch and run a central build on sapsailing.com. The dev branch is configured to run the Maven tests with direct Internet access. It can therefore also be used to run the tests locally if connected to the public Internet. + +Ideally, the build should be run including the test cases. If the tests succeed , the branch can be installed and the corresponding server instance can be restarted. The branch can then also be promoted to the next level (dev-->test-->prod1/prod2). Note, that currently re-starting a server instance may require re-loading the races that were previously loaded, particularly for the prod1 and prod2 instances, because several externally-announced URLs point to them. + +We typically promote the changes to the next branch by also merging the current master branch into the next-"higher" branch. This should lead to equivalent results compared to merging the "previous" branch (e.g., dev) into the "next" branch (e.g., test). The branches differ largely in the configurations used for the servers, particularly the port assignments for the Jetty web server, the UDP ports used for listening for Expedition wind messages, and the queue names used for the replication based on RabbitMQ (see also Scale-Out through Replication). + +## Eclipse Setup, Required Plug-Ins +We use Eclipse as our development environment. Using a different IDE would make it hard to re-use the project configurations (.project and .classpath files which are specific to Eclipse) as well as the GWT plug-in which assists in locally compiling and refactoring the GWT code, in particular the RPC code. + +The recommended and tested Eclipse version is currently Indigo (3.7). Colleagues have reported that they succeeded with a Juno (3.8/4.x) set-up as well. + +To get started, install Eclipse with at least PDE, Git, GWT (use http://dl.google.com/eclipse/plugin/3.7 as update site) and JSP editing support enabled. Eclipse Maven support is not recommended as in many cases it has caused trouble with the local Eclipse build. + +## Target Platform +After the Eclipse installation and importing all projects under java/ from Git, it is required to set the target platform in Eclipse (Window --> Preferences --> Plugin Development --> Target Platform). The project com.sap.sailing.targetplatform contains "Race Analysis Target (IDE)" as target platform definition. It uses a number of p2 update sites and defines the OSGi bundles that constitute the target platform for the application. If this is not set in Eclipse, the local build environment assumes that the developer wants to implement Eclipse plug-ins and offers the entire set of Eclipse plug-ins and only those as the target platform which doesn't make any sense for our application. + +Major parts of our target platform are hosted on sapsailing.com as a p2 repository which makes it possible to have only one central target platform configuration used by everyone. The target platform can be re-built, e.g., after adding another bundle to it, using the script in com.sap.sailing.targetplatform/scripts. + +It then needs to be installed again (by using a tool like scp for instance) to the /home/trac/p2-repositories directory from where it is exposed as http://sapcoe-app01.pironet-ndh.com/p2/sailing/ by the Apache web server. After such a change, all developers need to reload the target platform into their Eclipse environment. + +## Maven Build and Tests +We use Maven to build our software and run our JUnit tests. The global setting.xml file to install in everyone's ~/.m2 directory is checked into the top-level Git folder. The checked-in copy assumes the developer is using Maven inside the SAP corporate network. If not, uncomment the tag in the settings.xml file. See also section Git and Our Branches for details on which branch is configured to work in which network setup. + +We have a top-level Maven pom.xml configuration file in the root folder of our Git workspace. It delegates to the pom.xml file in the java/ folder where all the bundle projects are defined. We rely on the Tycho Maven plug-in to build our OSGi bundles, also known as the "manifest-first approach." The key idea is to mainly develop using Eclipse means, including its OSGi manifest editing capabilities, and keep the Maven infrastructure as simple as possible, deriving component dependencies from the OSGi manifests. See the various pom.xml files in the projects to see the project-specific settings. By and large, a pom.xml file for a bundle needs to have the bundle name and version defined (we currently have most bundles at version 1.0.0.qualifier in the manifest or 1.0.0.SNAPSHOT in Maven), and whether the bundle is a test or non-test bundle, expressed as the packaging type which here can be one of eclipse-plugin or ecplise-test-plugin. + +Test plugins automatically have their tests executed during a Maven build unless the command-line option -Dmaven.test.skip=true argument is specified. It is generally a good idea to launch the Maven command using the -fae option which asks Maven to continue until the end, even if errors or failures occurred on the way, failing at the end if any failures occurred. This can save numerous round trips and is useful in case of known and temporarily acceptable test failures. + +The Maven plug-in for the GWT compilation doesn't reliably perform a dependency check. It is therefore recommended to remove all contents of the java/com.sap.sailing.gwt.ui/com.sap.sailing.* folders (basically, all GWT compiler output) before launching the Maven build. A good command line for the Maven build from the java/ subdirectory in your local environment when outside the SAP VPN is this: + + buildAndUpdateProduct.sh build + +which basically does something like + + `rm -rf com.sap.sailing.gwt.ui/com.sap.sailing.*; mvn -fae -P debug.without-proxy clean install 2>&1 | tee log` + +Inside the SAP VPN you may want to use a different profile which accounts for the proxies that have to be used: + + buildAndUpdateProduct.sh -p build + +The buildAndUpdateProduct.sh script can be found in the top-level configuration/ directory in git. It has been used successfully in Linux and Cygwin environments. + +When building on sapsailing.com you should stick with the buildAndUpdateProduct.sh script. It makes a lot of settings that are necessary, such as specifying the settings.xml file to use for the Maven build. For the Selenium tests to succeed you have to make sure the DISPLAY environment variable is set to ":2.0" to send test browsers to a VNC display. Should the GWT build fail because it cannot open enough files, ensure the "ulimit -n" output is at least 4096 to enable the GWT compiler to assemble the resource sets which consist of many files that all need to be opened concurrently. Currently, the maximum value for "ulimit -n" is configured in /etc/security/limits.conf and is set to 16384. This specified the maximum amount to which a user's shell can set this value. The ~trac/.bash_profile contains a "ulimit -n 4096" command, but when running "screen" the shells usually are no login shells. You need to make sure you run ~trac/.bash_profile in the build shell to set the limit of open files to at least 4096. Then issue the respective buildAndUpdateProduct.sh command line. + +All these build lines also creates a log file with all error messages, just in case the screen buffer is not sufficient to hold all scrolling error messages. + +## Product and Features +The result of the build process is a p2 repository with a product consisting of a number of features. The product configuration is provided by the file raceanalysis.product in the com.sap.sailing.feature.p2build project. In its dependencies it defines the features of which it is built, which currently are com.sap.sailing.feature and com.sap.sailing.feature.runtime, each described in an equal-named bundle. + +The feature specified by com.sap.sailing.feature lists the bundles we develop ourselves as part of the project. The com.sap.sailing.feature.runtime feature lists those 3rd-party bundles from the target platform which are required by the product. + +## External Libraries + +### Highcharts and jQuery +We use the Highcharts library to present graphs to the user. These graphs are used on the RaceBoardPanel and (at the time of writing still under development) the PolarSheetsPanel. In the past, there were difficulties concerning the versions of the three interacting libraries: + +* The GWT Highcharts Wrapper – The source code can be found in our project and it’s slightly modified to match our scenario +* The actual Highcharts Library +* The jQuery Library + +To support polar diagrams we use version 3.5.0 of the wrapper. This version is tested with version 2.3.3 of the Highcharts library. We tried using 2.3.5 but that led to problems when resizing the RaceBoard. + +Highcharts uses the jQuery library. We do know that version 1.4.2 does NOT work with the versions of Highcharts mentioned above. Multiple yAxis are not initialized correctly. We know use version 1.5.2 of this library. From f3d185d1de5df2488f77e301effd0ae8c37c114b Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 8 Aug 2013 14:21:47 +0200 Subject: [PATCH 017/227] Updated development environment (markdown) --- wiki/development-environment.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/wiki/development-environment.md b/wiki/development-environment.md index 003faac8f00..4f4f151acae 100644 --- a/wiki/development-environment.md +++ b/wiki/development-environment.md @@ -25,7 +25,7 @@ After the Eclipse installation and importing all projects under java/ from Git, Major parts of our target platform are hosted on sapsailing.com as a p2 repository which makes it possible to have only one central target platform configuration used by everyone. The target platform can be re-built, e.g., after adding another bundle to it, using the script in com.sap.sailing.targetplatform/scripts. -It then needs to be installed again (by using a tool like scp for instance) to the /home/trac/p2-repositories directory from where it is exposed as http://sapcoe-app01.pironet-ndh.com/p2/sailing/ by the Apache web server. After such a change, all developers need to reload the target platform into their Eclipse environment. +It then needs to be installed again (by using a tool like scp for instance) to the /home/trac/p2-repositories directory from where it is exposed as http://p2.sapsailing.com/p2/sailing/ by the Apache web server. After such a change, all developers need to reload the target platform into their Eclipse environment. ## Maven Build and Tests We use Maven to build our software and run our JUnit tests. The global setting.xml file to install in everyone's ~/.m2 directory is checked into the top-level Git folder. The checked-in copy assumes the developer is using Maven inside the SAP corporate network. If not, uncomment the tag in the settings.xml file. See also section Git and Our Branches for details on which branch is configured to work in which network setup. @@ -52,10 +52,12 @@ When building on sapsailing.com you should stick with the buildAndUpdateProduct. All these build lines also creates a log file with all error messages, just in case the screen buffer is not sufficient to hold all scrolling error messages. -## Product and Features -The result of the build process is a p2 repository with a product consisting of a number of features. The product configuration is provided by the file raceanalysis.product in the com.sap.sailing.feature.p2build project. In its dependencies it defines the features of which it is built, which currently are com.sap.sailing.feature and com.sap.sailing.feature.runtime, each described in an equal-named bundle. +## Product, Features and Target Platform +The result of the build process is a p2 repository with a product consisting of a number of features. The product configuration is provided by the file raceanalysis.product in the com.sap.sailing.feature.p2build project. In its dependencies it defines the features of which it is built, which currently are com.sap.sailing.feature and com.sap.sailing.feature.runtime, each described in an equal-named bundle. The feature specified by com.sap.sailing.feature lists the bundles we develop ourselves as part of the project. The com.sap.sailing.feature.runtime feature lists those 3rd-party bundles from the target platform which are required by the product. -The feature specified by com.sap.sailing.feature lists the bundles we develop ourselves as part of the project. The com.sap.sailing.feature.runtime feature lists those 3rd-party bundles from the target platform which are required by the product. +The [target platform](#Target Platform) is defined in the various flavors for local and central environments in com.sap.sailing.targetplatform/definitions/*.target. It mainly uses Eclipse p2 repositories and our own p2 repository at http://p2.sapsailing.com/p2/sailing/ where we store those bundles required by our runtime which cannot be found as OSGi bundles in any other public p2 repository of which we are aware. + +This p2 repository at sapsailing.com can be re-built and correspondingly extended by the process explained [here](wiki/typical-development-scenarios#Adding-a-Bundle-to-the-Target-Platform). ## External Libraries From 78c74c8be70672b6cf31616fc72e8f992a402dd7 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 8 Aug 2013 14:22:35 +0200 Subject: [PATCH 018/227] Updated development environment (markdown) --- wiki/development-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/development-environment.md b/wiki/development-environment.md index 4f4f151acae..2d71c932363 100644 --- a/wiki/development-environment.md +++ b/wiki/development-environment.md @@ -55,7 +55,7 @@ All these build lines also creates a log file with all error messages, just in c ## Product, Features and Target Platform The result of the build process is a p2 repository with a product consisting of a number of features. The product configuration is provided by the file raceanalysis.product in the com.sap.sailing.feature.p2build project. In its dependencies it defines the features of which it is built, which currently are com.sap.sailing.feature and com.sap.sailing.feature.runtime, each described in an equal-named bundle. The feature specified by com.sap.sailing.feature lists the bundles we develop ourselves as part of the project. The com.sap.sailing.feature.runtime feature lists those 3rd-party bundles from the target platform which are required by the product. -The [target platform](#Target Platform) is defined in the various flavors for local and central environments in com.sap.sailing.targetplatform/definitions/*.target. It mainly uses Eclipse p2 repositories and our own p2 repository at http://p2.sapsailing.com/p2/sailing/ where we store those bundles required by our runtime which cannot be found as OSGi bundles in any other public p2 repository of which we are aware. +The [target platform](#Target-Platform) is defined in the various flavors for local and central environments in com.sap.sailing.targetplatform/definitions/*.target. It mainly uses Eclipse p2 repositories and our own p2 repository at http://p2.sapsailing.com/p2/sailing/ where we store those bundles required by our runtime which cannot be found as OSGi bundles in any other public p2 repository of which we are aware. This p2 repository at sapsailing.com can be re-built and correspondingly extended by the process explained [here](wiki/typical-development-scenarios#Adding-a-Bundle-to-the-Target-Platform). From abc83b28819130093a0dac4628d3be5463d0ee82 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 8 Aug 2013 14:33:36 +0200 Subject: [PATCH 019/227] Created local gwt (markdown) --- wiki/local-gwt.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 wiki/local-gwt.md diff --git a/wiki/local-gwt.md b/wiki/local-gwt.md new file mode 100644 index 00000000000..35864be3ed4 --- /dev/null +++ b/wiki/local-gwt.md @@ -0,0 +1,11 @@ +# Working with GWT Locally + +We're using GWT in a slightly non-standard way, combining it with the merits of OSGi and using separate GWT modules that are shared between server and client (such as com.sap.sailing.domain.common). Particularly the combination of GWT with OSGi comes with a few special arrangements and things that are noteworthy. + +## javax.servlet Version + +GWT comes with a built-in copy of the javax.servlet packages. However, in our environment, the servlet engine is provided by the Jetty bundles whose javax.servlet versions don't necessarily match with the one provided by the GWT version we use. To make the build use the javax.servlet version provided at runtime by Jetty, using the GWT classpath container that usually is added automatically to all GWT projects is detrimental to a proper build. That's why we have removed it in particular from the com.sap.sailing.gwt.ui project. + +Since the OSGi manifest dependencies still require javax.servlet, the Eclipse and Maven builds now use the correct Jetty-provided version of javax.servlet. However, not having the GWT classpath container on a GWT project's classpath unfortunately makes it impossible to use the GWT Eclipse plugin's neat GWT Compile feature. + +As a workaround, use the buildAndUpdateProduct.sh script found in the top-level configuration/ directory in git. Together with the -t and -c options (no tests, no cleaning), the compilation speed may be found acceptable. If you really urgently need to compile GWT locally on a regular basis and would like to speed up compilation, please consider temporarily editing java/com.sap.sailing.gwt.ui/pom.xml to reduce the number of modules and permutations to be compiled. \ No newline at end of file From a3d2e95967c8dbe43f0d6784589fd938dcee12cc Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 8 Aug 2013 14:41:32 +0200 Subject: [PATCH 020/227] Updated local gwt (markdown) --- wiki/local-gwt.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/wiki/local-gwt.md b/wiki/local-gwt.md index 35864be3ed4..09dbd74c4e5 100644 --- a/wiki/local-gwt.md +++ b/wiki/local-gwt.md @@ -2,10 +2,20 @@ We're using GWT in a slightly non-standard way, combining it with the merits of OSGi and using separate GWT modules that are shared between server and client (such as com.sap.sailing.domain.common). Particularly the combination of GWT with OSGi comes with a few special arrangements and things that are noteworthy. -## javax.servlet Version +## Some Background (javax.servlet Version) GWT comes with a built-in copy of the javax.servlet packages. However, in our environment, the servlet engine is provided by the Jetty bundles whose javax.servlet versions don't necessarily match with the one provided by the GWT version we use. To make the build use the javax.servlet version provided at runtime by Jetty, using the GWT classpath container that usually is added automatically to all GWT projects is detrimental to a proper build. That's why we have removed it in particular from the com.sap.sailing.gwt.ui project. Since the OSGi manifest dependencies still require javax.servlet, the Eclipse and Maven builds now use the correct Jetty-provided version of javax.servlet. However, not having the GWT classpath container on a GWT project's classpath unfortunately makes it impossible to use the GWT Eclipse plugin's neat GWT Compile feature. -As a workaround, use the buildAndUpdateProduct.sh script found in the top-level configuration/ directory in git. Together with the -t and -c options (no tests, no cleaning), the compilation speed may be found acceptable. If you really urgently need to compile GWT locally on a regular basis and would like to speed up compilation, please consider temporarily editing java/com.sap.sailing.gwt.ui/pom.xml to reduce the number of modules and permutations to be compiled. \ No newline at end of file +## Local GWT Compile + +As a workaround, use the buildAndUpdateProduct.sh script found in the top-level configuration/ directory in git. Together with the -t and -c options (no tests, no cleaning), the compilation speed may be found acceptable. If you really urgently need to compile GWT locally on a regular basis and would like to speed up compilation, please consider temporarily editing java/com.sap.sailing.gwt.ui/pom.xml to reduce the number of modules and permutations to be compiled. + +## Debugging GWT + +One of the great strengths of GWT is the use of Eclipse as a Java source-level debugging environment. To enjoy this feature, launch the SailingServer launch config appropriate for your environment (Proxy / No Proxy), then launch the SailingGWT launch configuration in debug mode. After a while it will show a "Development Mode" view that shows all entry points that have been initialized. Double-click on the one you want to debug, and your default browser (hopefully FireFox, because with other browsers the GWT debug plugin tends to be not very stable or not even present) will open. + +You can set breakpoints in your GWT Java code and inspect values for suspended threads as usual for any Java development. + +Note the reduced performance which is largely due to the way the Java VM and the browser plug-in communicate. In particular, many fine-grained changes to the DOM can be quite costly. Therefore, if you're only interested in server-side debugging, consider [compiling](Local-GWT-Compile) the GWT code for better performance. \ No newline at end of file From 732b1cdd8410dbb57a1827309af1e7ce7237cb19 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 8 Aug 2013 14:42:03 +0200 Subject: [PATCH 021/227] Updated local gwt (markdown) --- wiki/local-gwt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/local-gwt.md b/wiki/local-gwt.md index 09dbd74c4e5..1c0cf2bc0b9 100644 --- a/wiki/local-gwt.md +++ b/wiki/local-gwt.md @@ -18,4 +18,4 @@ One of the great strengths of GWT is the use of Eclipse as a Java source-level d You can set breakpoints in your GWT Java code and inspect values for suspended threads as usual for any Java development. -Note the reduced performance which is largely due to the way the Java VM and the browser plug-in communicate. In particular, many fine-grained changes to the DOM can be quite costly. Therefore, if you're only interested in server-side debugging, consider [compiling](Local-GWT-Compile) the GWT code for better performance. \ No newline at end of file +Note the reduced performance which is largely due to the way the Java VM and the browser plug-in communicate. In particular, many fine-grained changes to the DOM can be quite costly. Therefore, if you're only interested in server-side debugging, consider [compiling](#Local-GWT-Compile) the GWT code for better performance. \ No newline at end of file From 2580d388db2fde6d7c630411386264642087ddaf Mon Sep 17 00:00:00 2001 From: Riccardo Nimser Date: Thu, 8 Aug 2013 15:46:09 +0200 Subject: [PATCH 022/227] Updated selenium ui tests (markdown) --- wiki/selenium-ui-tests.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/wiki/selenium-ui-tests.md b/wiki/selenium-ui-tests.md index 910d0f8d4e8..b4cb052f88a 100644 --- a/wiki/selenium-ui-tests.md +++ b/wiki/selenium-ui-tests.md @@ -1,3 +1,35 @@ # UI Tests with Selenium -TODO to be filled in by Riccardo \ No newline at end of file +[[_TOC_]] + +To validate the web application from the user perspective we use a combination consisting of Selenium and JUnit, which allows us to simulate user interactions via a real browser instance. Therefore we provide a special JUnit-runner as well as different classes in the package com.sap.sailing.selenium.core to execute tests, using the Selenium WebDriver API, and to keep the execution of the tests as flexible as possible at the same time. + +To avoid duplicated and error prone code in test cases, we prefer the usage of the Page Object design pattern when writing automated UI tests. A page object is an object-oriented class that serves as an interface to the UI. The tests then use the methods of the page object class whenever they need to interact with the UI. The benefit is that if the UI changes, the tests themselves don’t need to be changed. Only the code within the page object needs to be changed. Subsequently all changes to support the new UI are located in one place. + +## Selenium Runner + +The Selenium runner is used to execute tests, using the Selenium WebDriver API. The runner takes a XML configuration file, which has to be provided via the system property selenium.test.environment.configuration, and runs the tests for each defined browser. The configuration file is needed to define the browsers with which the tests should be executed as well as to provide all the information to Selenium regarding to the web drivers. To avoid unnecessary errors we also provide a documented XML Schema for the configuration file. + +At runtime, the instance of the web driver along with additional information from the configuration is encapsulated by the interface TestEnvironment. The Selenium runner provides an instance to the tests by injecting it to fields of the correspondent type, annotated with Managed. With the class AbstractSeleniumTest we provide a skeletal implementation for tests, which already has all the necessary annotations applied. Furthermore this class provides a mechanism to automatically capture a screenshot in the case that a test fails. + +## Additional Classes + +Since GWT applications are heavily AJAX driven, one of the challenges in performing UI tests is to be able to tell when the application is in a state you expect. In simple cases you can wait until a loading animation disappears or until a well-known element has changed the state (e.g. visibility). However, since things are usually not that simple, especially in the context of GWT, it is more stable if we are able to tell exactly when an asynchronous request has finished. For this reason we use a counter for pending request which is incremented if an asynchronous callback is created and decremented when the callback completes, regardless of a success or a failure. With this counter a test which triggers a request (which can cause additional request) can wait until the counter reaches 0 again. + +The necessary JavaScript code for the counter is automatically injected in the host page by the provided class AbstractEntryPoint. With the class MarkedAsyncCallback we provide an abstract implementation of the AsyncCallback interface for asynchrony requests, which should be marked as pending until they complete using the introduced counter. Since the counter is incremented as soon as an instance is created, MarkedAsyncCallback is an object of single-use. Therefore it is strictly forbidden to create an instance of this class which is never used or which is used multiple times. Otherwise the counter will have an unpredictable value. + +## Page Object Pattern + +Within a web app's UI there are areas that tests interact with. A page object simply models these as objects within the test code and abstracts from the actual structure (DOM) of a website. This reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place. + +Page objects can be thought of as facing in two directions simultaneously. Facing towards the developer of a test, they represent the services offered by a particular page. Facing away from the developer, they should be the only thing that has a deep knowledge of the structure of a page (or part of a page). It's simplest to think of the methods on a page object as offering the "services" that a page offers rather than exposing the details and mechanics of the page. + +Because the developer of a test should think about the services that they're interacting with rather than the implementation, page objects should seldom expose the underlying web driver or elements. To facilitate this, methods on a page object should return other page objects. + +Since we prefer the usage of the Page Object design pattern when writing automated UI tests, we provide a base class PageObject as well as the two specializations HostPage and PageArea. The class HostPage represents a GWT entry point which waits for the completion of the GWT bootstrap process before it is initialized. The PageArea is used to represent a component or a specific area on a page, which is useful to improve maintainability for complex websites and reusable parts. + +There is a lot of flexibility in how the page objects may be designed, but there are a few basic rules for getting the desired maintainability of the test code. Page objects themselves should never be make verifications or assertions. This is part of the test and should always be within the test’s code, never in a page object. The page object will contain the representation of the page, and the services the page provides via methods but no code related to what is being tested should be within the page object. There is one, single, verification which can, and should, be within the page object and that is to verify that the page or the area, and possibly critical elements, were loaded correctly. This verification should be done while instantiating the page object. + +To make the development of page objects as simple and easy as possible, we also support a factory for this pattern which helps to remove some boiler-plate code from the page objects by using annotations. We provide the annotations FindBy and FindBys for fields on a page object to specify a mechanism for locating an element or a list of elements. The factory uses the annotations to lazily locate and wait for the element or the element list to appear, by polling the UI on a regular basis, and initializes the field with the element or the list of elements. + +Since we use GWT to build the UI, we also provide a specific mechanism to locate elements by the value of the GWT debug identifier. By convention we use the attribute selenium-id for the debug identifier which is implemented by the class AbstractEntryPoint. The class BySeleniumId defines the corresponding mechanism and locates an element or a list of elements by the value of the selenium-id attribute. \ No newline at end of file From 1055931cc27cd7ae56c2cddcc33de0d312d8aacd Mon Sep 17 00:00:00 2001 From: Riccardo Nimser Date: Thu, 8 Aug 2013 15:53:54 +0200 Subject: [PATCH 023/227] Updated selenium ui tests (markdown) --- wiki/selenium-ui-tests.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/wiki/selenium-ui-tests.md b/wiki/selenium-ui-tests.md index b4cb052f88a..17baa7f63dc 100644 --- a/wiki/selenium-ui-tests.md +++ b/wiki/selenium-ui-tests.md @@ -2,21 +2,23 @@ [[_TOC_]] -To validate the web application from the user perspective we use a combination consisting of Selenium and JUnit, which allows us to simulate user interactions via a real browser instance. Therefore we provide a special JUnit-runner as well as different classes in the package com.sap.sailing.selenium.core to execute tests, using the Selenium WebDriver API, and to keep the execution of the tests as flexible as possible at the same time. +## General + +To validate the web application from the user perspective we use a combination consisting of Selenium and JUnit, which allows us to simulate user interactions via a real browser instance. Therefore we provide a special JUnit-runner as well as different classes in the package _com.sap.sailing.selenium.core_ to execute tests, using the Selenium WebDriver API, and to keep the execution of the tests as flexible as possible at the same time. To avoid duplicated and error prone code in test cases, we prefer the usage of the Page Object design pattern when writing automated UI tests. A page object is an object-oriented class that serves as an interface to the UI. The tests then use the methods of the page object class whenever they need to interact with the UI. The benefit is that if the UI changes, the tests themselves don’t need to be changed. Only the code within the page object needs to be changed. Subsequently all changes to support the new UI are located in one place. ## Selenium Runner -The Selenium runner is used to execute tests, using the Selenium WebDriver API. The runner takes a XML configuration file, which has to be provided via the system property selenium.test.environment.configuration, and runs the tests for each defined browser. The configuration file is needed to define the browsers with which the tests should be executed as well as to provide all the information to Selenium regarding to the web drivers. To avoid unnecessary errors we also provide a documented XML Schema for the configuration file. +The Selenium runner is used to execute tests, using the Selenium WebDriver API. The runner takes a XML configuration file, which has to be provided via the system property _selenium.test.environment.configuration_, and runs the tests for each defined browser. The configuration file is needed to define the browsers with which the tests should be executed as well as to provide all the information to Selenium regarding to the web drivers. To avoid unnecessary errors we also provide a documented XML Schema for the configuration file. -At runtime, the instance of the web driver along with additional information from the configuration is encapsulated by the interface TestEnvironment. The Selenium runner provides an instance to the tests by injecting it to fields of the correspondent type, annotated with Managed. With the class AbstractSeleniumTest we provide a skeletal implementation for tests, which already has all the necessary annotations applied. Furthermore this class provides a mechanism to automatically capture a screenshot in the case that a test fails. +At runtime, the instance of the web driver along with additional information from the configuration is encapsulated by the interface _TestEnvironment_. The Selenium runner provides an instance to the tests by injecting it to fields of the correspondent type, annotated with _Managed_. With the class _AbstractSeleniumTest_ we provide a skeletal implementation for tests, which already has all the necessary annotations applied. Furthermore this class provides a mechanism to automatically capture a screenshot in the case that a test fails. ## Additional Classes Since GWT applications are heavily AJAX driven, one of the challenges in performing UI tests is to be able to tell when the application is in a state you expect. In simple cases you can wait until a loading animation disappears or until a well-known element has changed the state (e.g. visibility). However, since things are usually not that simple, especially in the context of GWT, it is more stable if we are able to tell exactly when an asynchronous request has finished. For this reason we use a counter for pending request which is incremented if an asynchronous callback is created and decremented when the callback completes, regardless of a success or a failure. With this counter a test which triggers a request (which can cause additional request) can wait until the counter reaches 0 again. -The necessary JavaScript code for the counter is automatically injected in the host page by the provided class AbstractEntryPoint. With the class MarkedAsyncCallback we provide an abstract implementation of the AsyncCallback interface for asynchrony requests, which should be marked as pending until they complete using the introduced counter. Since the counter is incremented as soon as an instance is created, MarkedAsyncCallback is an object of single-use. Therefore it is strictly forbidden to create an instance of this class which is never used or which is used multiple times. Otherwise the counter will have an unpredictable value. +The necessary JavaScript code for the counter is automatically injected in the host page by the provided class _AbstractEntryPoint_. With the class _MarkedAsyncCallback_ we provide an abstract implementation of the _AsyncCallback_ interface for asynchrony requests, which should be marked as pending until they complete using the introduced counter. Since the counter is incremented as soon as an instance is created, _MarkedAsyncCallback_ is an object of single-use. Therefore it is strictly forbidden to create an instance of this class which is never used or which is used multiple times. Otherwise the counter will have an unpredictable value. ## Page Object Pattern @@ -26,10 +28,10 @@ Page objects can be thought of as facing in two directions simultaneously. Facin Because the developer of a test should think about the services that they're interacting with rather than the implementation, page objects should seldom expose the underlying web driver or elements. To facilitate this, methods on a page object should return other page objects. -Since we prefer the usage of the Page Object design pattern when writing automated UI tests, we provide a base class PageObject as well as the two specializations HostPage and PageArea. The class HostPage represents a GWT entry point which waits for the completion of the GWT bootstrap process before it is initialized. The PageArea is used to represent a component or a specific area on a page, which is useful to improve maintainability for complex websites and reusable parts. +Since we prefer the usage of the Page Object design pattern when writing automated UI tests, we provide a base class _PageObject_ as well as the two specializations _HostPage_ and _PageArea_. The class _HostPage_ represents a GWT entry point which waits for the completion of the GWT bootstrap process before it is initialized. The _PageArea_ is used to represent a component or a specific area on a page, which is useful to improve maintainability for complex websites and reusable parts. There is a lot of flexibility in how the page objects may be designed, but there are a few basic rules for getting the desired maintainability of the test code. Page objects themselves should never be make verifications or assertions. This is part of the test and should always be within the test’s code, never in a page object. The page object will contain the representation of the page, and the services the page provides via methods but no code related to what is being tested should be within the page object. There is one, single, verification which can, and should, be within the page object and that is to verify that the page or the area, and possibly critical elements, were loaded correctly. This verification should be done while instantiating the page object. -To make the development of page objects as simple and easy as possible, we also support a factory for this pattern which helps to remove some boiler-plate code from the page objects by using annotations. We provide the annotations FindBy and FindBys for fields on a page object to specify a mechanism for locating an element or a list of elements. The factory uses the annotations to lazily locate and wait for the element or the element list to appear, by polling the UI on a regular basis, and initializes the field with the element or the list of elements. +To make the development of page objects as simple and easy as possible, we also support a factory for this pattern which helps to remove some boiler-plate code from the page objects by using annotations. We provide the annotations _FindBy_ and _FindBys_ for fields on a page object to specify a mechanism for locating an element or a list of elements. The factory uses the annotations to lazily locate and wait for the element or the element list to appear, by polling the UI on a regular basis, and initializes the field with the element or the list of elements. -Since we use GWT to build the UI, we also provide a specific mechanism to locate elements by the value of the GWT debug identifier. By convention we use the attribute selenium-id for the debug identifier which is implemented by the class AbstractEntryPoint. The class BySeleniumId defines the corresponding mechanism and locates an element or a list of elements by the value of the selenium-id attribute. \ No newline at end of file +Since we use GWT to build the UI, we also provide a specific mechanism to locate elements by the value of the GWT debug identifier. By convention we use the attribute selenium-id for the debug identifier which is implemented by the class _AbstractEntryPoint_. The class _BySeleniumId_ defines the corresponding mechanism and locates an element or a list of elements by the value of the selenium-id attribute. \ No newline at end of file From 005e0be12230dcbbf69389720f384d023ee58cc5 Mon Sep 17 00:00:00 2001 From: Riccardo Nimser Date: Thu, 8 Aug 2013 15:54:51 +0200 Subject: [PATCH 024/227] Updated selenium ui tests (markdown) --- wiki/selenium-ui-tests.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wiki/selenium-ui-tests.md b/wiki/selenium-ui-tests.md index 17baa7f63dc..cad4db949c6 100644 --- a/wiki/selenium-ui-tests.md +++ b/wiki/selenium-ui-tests.md @@ -34,4 +34,7 @@ There is a lot of flexibility in how the page objects may be designed, but there To make the development of page objects as simple and easy as possible, we also support a factory for this pattern which helps to remove some boiler-plate code from the page objects by using annotations. We provide the annotations _FindBy_ and _FindBys_ for fields on a page object to specify a mechanism for locating an element or a list of elements. The factory uses the annotations to lazily locate and wait for the element or the element list to appear, by polling the UI on a regular basis, and initializes the field with the element or the list of elements. -Since we use GWT to build the UI, we also provide a specific mechanism to locate elements by the value of the GWT debug identifier. By convention we use the attribute selenium-id for the debug identifier which is implemented by the class _AbstractEntryPoint_. The class _BySeleniumId_ defines the corresponding mechanism and locates an element or a list of elements by the value of the selenium-id attribute. \ No newline at end of file +Since we use GWT to build the UI, we also provide a specific mechanism to locate elements by the value of the GWT debug identifier. By convention we use the attribute selenium-id for the debug identifier which is implemented by the class _AbstractEntryPoint_. The class _BySeleniumId_ defines the corresponding mechanism and locates an element or a list of elements by the value of the selenium-id attribute. + +## Writing and Execution of Tests + From 25de363cdbb60dc19a1b7c062a8579825429e7be Mon Sep 17 00:00:00 2001 From: Riccardo Nimser Date: Thu, 8 Aug 2013 15:58:27 +0200 Subject: [PATCH 025/227] Updated selenium ui tests (markdown) --- wiki/selenium-ui-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/selenium-ui-tests.md b/wiki/selenium-ui-tests.md index cad4db949c6..c589320eab1 100644 --- a/wiki/selenium-ui-tests.md +++ b/wiki/selenium-ui-tests.md @@ -34,7 +34,7 @@ There is a lot of flexibility in how the page objects may be designed, but there To make the development of page objects as simple and easy as possible, we also support a factory for this pattern which helps to remove some boiler-plate code from the page objects by using annotations. We provide the annotations _FindBy_ and _FindBys_ for fields on a page object to specify a mechanism for locating an element or a list of elements. The factory uses the annotations to lazily locate and wait for the element or the element list to appear, by polling the UI on a regular basis, and initializes the field with the element or the list of elements. -Since we use GWT to build the UI, we also provide a specific mechanism to locate elements by the value of the GWT debug identifier. By convention we use the attribute selenium-id for the debug identifier which is implemented by the class _AbstractEntryPoint_. The class _BySeleniumId_ defines the corresponding mechanism and locates an element or a list of elements by the value of the selenium-id attribute. +Since we use GWT to build the UI, we also provide a specific mechanism to locate elements by the value of the GWT debug identifier. By convention we use the attribute _selenium-id_ for the debug identifier which is implemented by the class _AbstractEntryPoint_. The class _BySeleniumId_ defines the corresponding mechanism and locates an element or a list of elements by the value of the selenium-id attribute. ## Writing and Execution of Tests From 1174fef2b917dcd8199d92aaeed1c8997590c0db Mon Sep 17 00:00:00 2001 From: Riccardo Nimser Date: Thu, 8 Aug 2013 16:09:34 +0200 Subject: [PATCH 026/227] Updated selenium ui tests (markdown) --- wiki/selenium-ui-tests.md | 1 + 1 file changed, 1 insertion(+) diff --git a/wiki/selenium-ui-tests.md b/wiki/selenium-ui-tests.md index c589320eab1..9b84965da42 100644 --- a/wiki/selenium-ui-tests.md +++ b/wiki/selenium-ui-tests.md @@ -38,3 +38,4 @@ Since we use GWT to build the UI, we also provide a specific mechanism to locate ## Writing and Execution of Tests +**TODO by Riccardo** \ No newline at end of file From b3637ae5d75e848a0b04f2f5d054134d81d1a4a8 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Fri, 9 Aug 2013 00:08:07 +0200 Subject: [PATCH 027/227] Created racecommittee app (markdown) --- racecommittee-app.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 racecommittee-app.md diff --git a/racecommittee-app.md b/racecommittee-app.md new file mode 100644 index 00000000000..c8905911b6f --- /dev/null +++ b/racecommittee-app.md @@ -0,0 +1 @@ +Under Construction \ No newline at end of file From 10c217a8c167e6ac622a686dc4be7bb37e63cd83 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Fri, 9 Aug 2013 00:08:43 +0200 Subject: [PATCH 028/227] Updated home (markdown) --- home.md | 1 + 1 file changed, 1 insertion(+) diff --git a/home.md b/home.md index 9f9d46a31ce..4f35aa7dc23 100644 --- a/home.md +++ b/home.md @@ -30,6 +30,7 @@ Like businesses, sailors need the latest information to make strategic decisions * [[Sailing Domain Algorithms|wiki/sailing-domain-algorithms]] * [[Inventory|wiki/inventar-liste]] * [[Smartphone Tracking|wiki/smartphone-tracking]] + * [[Racecommittee App|wiki/racecommittee-app]] * Planning and Event Information * [[Project Planning (bigger development)|wiki/planning]] * [[General Event Planning|wiki/general-event-planning]] From 4558aad9f4b8f4955a9cb2b481eed4e9f54df9e6 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Fri, 9 Aug 2013 00:09:12 +0200 Subject: [PATCH 029/227] Updated racecommittee app (markdown) --- racecommittee-app.md | 1 - 1 file changed, 1 deletion(-) diff --git a/racecommittee-app.md b/racecommittee-app.md index c8905911b6f..e69de29bb2d 100644 --- a/racecommittee-app.md +++ b/racecommittee-app.md @@ -1 +0,0 @@ -Under Construction \ No newline at end of file From d4726432418e2de31885b34eb0de9bb65c7edb9b Mon Sep 17 00:00:00 2001 From: Potsdam Date: Fri, 9 Aug 2013 00:09:29 +0200 Subject: [PATCH 030/227] Created racecommittee app (markdown) --- wiki/racecommittee-app.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 wiki/racecommittee-app.md diff --git a/wiki/racecommittee-app.md b/wiki/racecommittee-app.md new file mode 100644 index 00000000000..c8905911b6f --- /dev/null +++ b/wiki/racecommittee-app.md @@ -0,0 +1 @@ +Under Construction \ No newline at end of file From 85dadd9c21c874accfcdca8f83c49ce7edc13c60 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Fri, 9 Aug 2013 00:09:49 +0200 Subject: [PATCH 031/227] Updated racecommittee app (markdown) From 6841a0547ca6ea434f3db7dbc9b8578d53724c88 Mon Sep 17 00:00:00 2001 From: Potsdam Date: Fri, 9 Aug 2013 00:10:48 +0200 Subject: [PATCH 032/227] Updated racecommittee app (markdown) --- wiki/racecommittee-app.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/wiki/racecommittee-app.md b/wiki/racecommittee-app.md index c8905911b6f..926b52e0332 100644 --- a/wiki/racecommittee-app.md +++ b/wiki/racecommittee-app.md @@ -1 +1,11 @@ -Under Construction \ No newline at end of file +# RaceCommittee App + +[[_TOC_]] + +## Introduction + +## Features + +## Course Designer + +## Etc \ No newline at end of file From bf95cd473519a03da977e6c3714eec7f2ee9415c Mon Sep 17 00:00:00 2001 From: Jan Bross Date: Fri, 9 Aug 2013 13:53:19 +0200 Subject: [PATCH 033/227] Updated smartphone tracking (markdown) --- wiki/smartphone-tracking.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/wiki/smartphone-tracking.md b/wiki/smartphone-tracking.md index b43fe6fc949..5e38c5243f6 100644 --- a/wiki/smartphone-tracking.md +++ b/wiki/smartphone-tracking.md @@ -214,21 +214,25 @@ Sends the location information to a web service. ### `SAP Sailor Tracker Service` Background process for starting, pausing and stopping tracking. Registers all receivers on a pending intent, which is send periodically. -### `doPostTask` -Async task that handles the execution of post requests. +### `AsyncJsonPostTask` +Async task that handles the execution of post requests with Json content. -### `doGetTask` -Async task that handles the execution of get requests. +### `OnlineDataManager` +Enables accessing of data from the DataStore. Loads data from Servlets using GET-Requests via a DataLoader. Usage for example in SelectRaceFragment, which loads the RaceLogsInPreRacePhase so that the user can select the race he wants to take part in. + +### `DataStore` +Interface for the DataStore which stores all data that is relevant for the App (managed Races, Competitors, ...) +Implementation: `InMemoryDataStore` + +### `DataLoader` +AsyncDataLoader which does an HTTP GET to a given URL, parses the data (with a DataParser) and sends the data to a DataHandler. ### `AppPreferences` Helper Class for accessing the App Preferences specified in settings_view.xml -### `DataStore` -Interface for the DataStore which stores all data that is relevant for the App (managed Races, Competitors, ...) -Implementation: InMemoryDataStore - -### `DataLoader` -AsyncDataLoader which does an HTTP GET to a given URL, parses the data (with a DataParser) and sends the data to a DataHandler. +### `ListFragmentWithDataManager` +Base Class, which provides easy access to the data manager for a Fragment, which wants to display the data in a List. +Used for example in the Select*Fragments. ## ToDo From 20325412977df370ca969267ddfdae7dbcbd88a0 Mon Sep 17 00:00:00 2001 From: Jan Bross Date: Fri, 9 Aug 2013 13:58:04 +0200 Subject: [PATCH 034/227] Updated smartphone tracking (markdown) --- wiki/smartphone-tracking.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/wiki/smartphone-tracking.md b/wiki/smartphone-tracking.md index 5e38c5243f6..2e8df493a9c 100644 --- a/wiki/smartphone-tracking.md +++ b/wiki/smartphone-tracking.md @@ -218,25 +218,26 @@ Background process for starting, pausing and stopping tracking. Registers all re Async task that handles the execution of post requests with Json content. ### `OnlineDataManager` -Enables accessing of data from the DataStore. Loads data from Servlets using GET-Requests via a DataLoader. Usage for example in SelectRaceFragment, which loads the RaceLogsInPreRacePhase so that the user can select the race he wants to take part in. +Enables accessing of data from a `DataStore`. Loads data from Servlets using GET-Requests using a `DataLoader`. For an example how to use the `OnlineDataManager` refer to `SelectRaceFragment`, which loads the RaceLogsInPreRacePhase so that the user can select the race he wants to take part in. ### `DataStore` -Interface for the DataStore which stores all data that is relevant for the App (managed Races, Competitors, ...) +Interface for the `DataStore` which stores all data that is relevant for the App (managed Races, Competitors, ...) Implementation: `InMemoryDataStore` ### `DataLoader` -AsyncDataLoader which does an HTTP GET to a given URL, parses the data (with a DataParser) and sends the data to a DataHandler. +`AsyncDataLoader` which does an HTTP GET to a given URL, parses the data (with a `DataParser`) and sends the data to a `DataHandler`. ### `AppPreferences` Helper Class for accessing the App Preferences specified in settings_view.xml ### `ListFragmentWithDataManager` Base Class, which provides easy access to the data manager for a Fragment, which wants to display the data in a List. -Used for example in the Select*Fragments. +Used for example in the `Select*Fragments`. ## ToDo ### Server +* use ManagedRaceIdentifier or RaceLogIdenifier instead String-Triple as response type for the * set fleet when creating race * editing course in the RaceBoardAdmin * persist tracking data (GPSFixStore) From 04ac32301e52029fd1d75ff9ff94ff0fec3df874 Mon Sep 17 00:00:00 2001 From: Jan Bross Date: Fri, 9 Aug 2013 14:00:31 +0200 Subject: [PATCH 035/227] Updated smartphone tracking (markdown) --- wiki/smartphone-tracking.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wiki/smartphone-tracking.md b/wiki/smartphone-tracking.md index 2e8df493a9c..f67a1aad084 100644 --- a/wiki/smartphone-tracking.md +++ b/wiki/smartphone-tracking.md @@ -237,7 +237,7 @@ Used for example in the `Select*Fragments`. ## ToDo ### Server -* use ManagedRaceIdentifier or RaceLogIdenifier instead String-Triple as response type for the +* use ManagedRaceIdentifier or RaceLogIdenifier instead String-Triple as response type for the GetRaceLogsInPreRacePhaseServlet and the CreateRaceServlet * set fleet when creating race * editing course in the RaceBoardAdmin * persist tracking data (GPSFixStore) @@ -255,6 +255,7 @@ Used for example in the `Select*Fragments`. * Servlet for getting Competitors for a certain race: Have a look how this is implemented in the serverside-counterpart of the racecommittee-app: /sailingserver/rc/competitors?leaderboard="+raceGroupName+"&raceColumn"+raceColumnName+ "&fleet="+fleetName ### Android +* think about how to use the CompetitorJsonDeserializer in the App as DomainFactory-Class is in the com.sap.sailing.domain.base package and therefore causes a ClassNotFoundException * reuse existing course design functionality to create RaceLogCourseDesignChangedEvent before sending RaceLogPreRacePhaseEndedEvent * abstract sending service, so that all POST / GET requests and not only RaceLogEvents can be sent using the semi-connectedness functionality --> just write JSONObjects/Strings directly into the file. The Servlet has to handle deserialization and the client doesn't have to know what type of object it is after having saved it (is this really the case?) * simplify settings From ea6b2cfe44518ad57137a1027272804b3d55bb03 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Wed, 14 Aug 2013 16:04:35 +0200 Subject: [PATCH 036/227] Updated home (markdown) --- home.md | 1 + 1 file changed, 1 insertion(+) diff --git a/home.md b/home.md index 4f35aa7dc23..17f86d8fe4c 100644 --- a/home.md +++ b/home.md @@ -31,6 +31,7 @@ Like businesses, sailors need the latest information to make strategic decisions * [[Inventory|wiki/inventar-liste]] * [[Smartphone Tracking|wiki/smartphone-tracking]] * [[Racecommittee App|wiki/racecommittee-app]] + * [[Web Services API|wiki/sailing-webservices]] * Planning and Event Information * [[Project Planning (bigger development)|wiki/planning]] * [[General Event Planning|wiki/general-event-planning]] From b0ad04d84e6647d30143b67bc65066a2d931f687 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Wed, 14 Aug 2013 16:05:55 +0200 Subject: [PATCH 037/227] Created sailing webservices (markdown) --- wiki/sailing-webservices.md | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 wiki/sailing-webservices.md diff --git a/wiki/sailing-webservices.md b/wiki/sailing-webservices.md new file mode 100644 index 00000000000..1ff26caa182 --- /dev/null +++ b/wiki/sailing-webservices.md @@ -0,0 +1,50 @@ +# Sailing Web-Services API +For all service URLs, please note that we use an Apache reverse proxy to map URLs (and in particular the sub-domain) to a particular server instance. So, www.sapsailing.com may end up on a different server instance than tw2013.sapsailing.com or ess40-2013.sapsailing.com. Usually, we hand out a per-event or per-series URL, such as the ones above (except www.sapsailing.com which is the general landing page), and you would only fetch the content for the event you're interested in, even if the server instance has more. + +In all subsequent explanations, you may replace the "www.sapsailing.com" hostname by an according per-event host name to make sure you get to the event you're interested in. + +To get an overview of which regattas a server offers, use + +http://www.sapsailing.com/sailingserver/regattas + +It lists regattas with their name, scoringSystem and boatclass attributes. Using the regatta name as the "name" parameter in the following service: + +http://www.sapsailing.com/sailingserver/regatta?name=ESS+2012+Cardiff+(Extreme40) + +you will obtain a JSON document that has the regatta structure with its series and fleets, the names of the races in the regatta and some overview data for each race including the name, whether it's a so-called "medal race" (usually resulting in double points), whether it's live (isLive), whether we have tracking data for it (isTracked) and the name of the tracked race (trackedRace) which may be null in case isTracked==false. The trackedRace value can be used in other services to obtain more details about the race. + +Here is an example of using the wind service, based on the regatta name and the trackedRaceName of the regatta service: + +http://www.sapsailing.com/sailingserver/wind?regattaname=ESS%202012%20Cardiff%20%28Extreme40%29&racename=Cardiff%20Race12&windsource=COMBINED + +Note that there is also a latdeg and lngdev field in the wind fixes in case you want to plot the wind value somewhere on the map. You can also omit the windsource parameter and will get the complete set of wind data for the race where you can also see the different wind source names, such as "EXPEDITION (6)" denoting one of several wind measurement devices, TRACK_BASED_ESTIMATION indicating what we estimate from the boats' courses, and the well-known COMBINED wind source which adds it all up. + +As I mentioned during our call, there are still some legacy services that haven't been used in a while but which may get you started quickly. We can clean this up later to make things more consistent also on our end. + +The service you can use to obtain more details about a particular race, using the above example, works as follows: + +http://www.sapsailing.com/sailingserver/moderator?action=showrace®attaname=ESS%202012%20Cardiff%20%28Extreme40%29&racename=Cardiff%20Race12 + +I attach a README that has some bits of documentation on those legacy web services which still should work as described there. Note in particular that this service grants you time-dependent access to a number of key figures for each competitor which may be of interest also for your "hawk eye view," such as all competitors' current speed over ground, distance traveled, rank, gap to leader, estimated time to next mark and whether the competitors has already started / finished that leg. If you don't provide a time point, the current time will be used for the query, usually giving you the data for the end of the race for past races, and the current data for a live race. + +To obtain information about the waypoint positions, use + +http://www.sapsailing.com/sailingserver/moderator?action=showwaypoints®attaname=ESS%202012%20Cardiff%20%28Extreme40%29&racename=Cardiff%20Race12 + +A race course may use the same point several times, giving you multiple waypoints referring to the same so-called control point. A control point, in turn, can either be a single mark or can be made up of two marks as for the start and finish line or a gate for which the competitors can choose which mark to round. The service emits the GPS positions for each individual mark, grouped by the control point to which they belong, inside the waypoint referencing this control point. The control point names are unique within a course, and you will therefore see equal lat/lng values for the same control point occurring multiple times in the document in case the course uses the same control point in multiple waypoints. + +Finally, + +http://www.sapsailing.com/sailingserver/moderator?action=showboatpositions®attaname=ESS%202012%20Cardiff%20%28Extreme40%29&racename=Cardiff%20Race12 + +lists all GPS fixes for the boats. If no from/to time points are specified, this will send you a document that contains all GPS fixes for all boats for the entire race. Each fix has the timepoint, latdeg/lngdeg, truebearingdeg (which may better be referred to as a course over ground or COG for short), the speed in knots (knotspeed) and the tack ("STARBOARD" or "PORT", telling from which side the boat has the wind coming which decides, among other things, who has to yield to avoid collisions). The tack may also help you visualizing the boat properly, with the sails on the right side (on starboard for PORT tack and vice versa). + +Please note that the trackedRaceName values (such as "Cardif Race12") usually differ from the race (column) names used in the leaderboards where we rather use short names such as "R12". + +There can be two different types of leaderboards: regatta leaderboards and flexible leaderboards. The leaderboard group document tells you which is which. See the isRegattaLeaderboard attribute in the leaderboard elements. For flexible leaderboards, the leaderboard group document tells the connection between the leaderboards and the tracked races. See + +http://www.sapsailing.com/sailingserver/leaderboardgroup?leaderboardGroupName=Extreme%20Sailing%20Series%202012 + +where you can see the tracked race linked to the leaderboard columns with their trackedRaceName. Unfortunately, the regattaName attribute is missing for the flexible leaderboards which you need to get all parameters for the showwind, showboatpositions, showwaypoints and showrace services. I'll add that now and let you know when it's done. + +I recommend to let user navigate the data available starting with the list of leaderboard groups available in the server (http://www.sapsailing.com/sailingserver/leaderboardgroups). From there, you can obtain the structure of all leaderboards in those groups. For regatta leaderboards, the leaderboardgroup service tells the regatta name which you can use in http://www.sapsailing.com/sailingserver/regatta?name=ESS+2012+Cardiff+%28Extreme40%29 and which then tells you the regatta structure and provides the links to the tracked races. For flexible leaderboards, you have the trackedRaceName and (soon) the regattaName attribute available in the leaderboardgroup document which lets you navigate to showboatpositions, showwaypoints, showrace and the wind service. \ No newline at end of file From 7efb434155e9f69cae509394a5fd2cece935db12 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Wed, 14 Aug 2013 16:07:15 +0200 Subject: [PATCH 038/227] Updated sailing webservices (markdown) --- wiki/sailing-webservices.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/wiki/sailing-webservices.md b/wiki/sailing-webservices.md index 1ff26caa182..03e58dd5cf4 100644 --- a/wiki/sailing-webservices.md +++ b/wiki/sailing-webservices.md @@ -3,16 +3,22 @@ For all service URLs, please note that we use an Apache reverse proxy to map URL In all subsequent explanations, you may replace the "www.sapsailing.com" hostname by an according per-event host name to make sure you get to the event you're interested in. +## Regatta Overview + To get an overview of which regattas a server offers, use http://www.sapsailing.com/sailingserver/regattas +## Single Regatta + It lists regattas with their name, scoringSystem and boatclass attributes. Using the regatta name as the "name" parameter in the following service: http://www.sapsailing.com/sailingserver/regatta?name=ESS+2012+Cardiff+(Extreme40) you will obtain a JSON document that has the regatta structure with its series and fleets, the names of the races in the regatta and some overview data for each race including the name, whether it's a so-called "medal race" (usually resulting in double points), whether it's live (isLive), whether we have tracking data for it (isTracked) and the name of the tracked race (trackedRace) which may be null in case isTracked==false. The trackedRace value can be used in other services to obtain more details about the race. +## Wind Information + Here is an example of using the wind service, based on the regatta name and the trackedRaceName of the regatta service: http://www.sapsailing.com/sailingserver/wind?regattaname=ESS%202012%20Cardiff%20%28Extreme40%29&racename=Cardiff%20Race12&windsource=COMBINED @@ -21,19 +27,23 @@ Note that there is also a latdeg and lngdev field in the wind fixes in case you As I mentioned during our call, there are still some legacy services that haven't been used in a while but which may get you started quickly. We can clean this up later to make things more consistent also on our end. +## Tracked Race + The service you can use to obtain more details about a particular race, using the above example, works as follows: http://www.sapsailing.com/sailingserver/moderator?action=showrace®attaname=ESS%202012%20Cardiff%20%28Extreme40%29&racename=Cardiff%20Race12 I attach a README that has some bits of documentation on those legacy web services which still should work as described there. Note in particular that this service grants you time-dependent access to a number of key figures for each competitor which may be of interest also for your "hawk eye view," such as all competitors' current speed over ground, distance traveled, rank, gap to leader, estimated time to next mark and whether the competitors has already started / finished that leg. If you don't provide a time point, the current time will be used for the query, usually giving you the data for the end of the race for past races, and the current data for a live race. +## Waypoint Positions + To obtain information about the waypoint positions, use http://www.sapsailing.com/sailingserver/moderator?action=showwaypoints®attaname=ESS%202012%20Cardiff%20%28Extreme40%29&racename=Cardiff%20Race12 A race course may use the same point several times, giving you multiple waypoints referring to the same so-called control point. A control point, in turn, can either be a single mark or can be made up of two marks as for the start and finish line or a gate for which the competitors can choose which mark to round. The service emits the GPS positions for each individual mark, grouped by the control point to which they belong, inside the waypoint referencing this control point. The control point names are unique within a course, and you will therefore see equal lat/lng values for the same control point occurring multiple times in the document in case the course uses the same control point in multiple waypoints. -Finally, +## GPS Fixes for Boats http://www.sapsailing.com/sailingserver/moderator?action=showboatpositions®attaname=ESS%202012%20Cardiff%20%28Extreme40%29&racename=Cardiff%20Race12 From 389365759d1f9a3bc9003333f839d94848f6d369 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Wed, 14 Aug 2013 16:07:30 +0200 Subject: [PATCH 039/227] Updated sailing webservices (markdown) --- wiki/sailing-webservices.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wiki/sailing-webservices.md b/wiki/sailing-webservices.md index 03e58dd5cf4..805dcb6c51b 100644 --- a/wiki/sailing-webservices.md +++ b/wiki/sailing-webservices.md @@ -1,4 +1,7 @@ # Sailing Web-Services API + +[[TOC]] + For all service URLs, please note that we use an Apache reverse proxy to map URLs (and in particular the sub-domain) to a particular server instance. So, www.sapsailing.com may end up on a different server instance than tw2013.sapsailing.com or ess40-2013.sapsailing.com. Usually, we hand out a per-event or per-series URL, such as the ones above (except www.sapsailing.com which is the general landing page), and you would only fetch the content for the event you're interested in, even if the server instance has more. In all subsequent explanations, you may replace the "www.sapsailing.com" hostname by an according per-event host name to make sure you get to the event you're interested in. From 8d8b493692c84cc0ea19fd6efc6ff6c55202c955 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Wed, 14 Aug 2013 16:07:40 +0200 Subject: [PATCH 040/227] Updated sailing webservices (markdown) --- wiki/sailing-webservices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/sailing-webservices.md b/wiki/sailing-webservices.md index 805dcb6c51b..acd9f92b7be 100644 --- a/wiki/sailing-webservices.md +++ b/wiki/sailing-webservices.md @@ -1,6 +1,6 @@ # Sailing Web-Services API -[[TOC]] +[[_TOC_]] For all service URLs, please note that we use an Apache reverse proxy to map URLs (and in particular the sub-domain) to a particular server instance. So, www.sapsailing.com may end up on a different server instance than tw2013.sapsailing.com or ess40-2013.sapsailing.com. Usually, we hand out a per-event or per-series URL, such as the ones above (except www.sapsailing.com which is the general landing page), and you would only fetch the content for the event you're interested in, even if the server instance has more. From e3ea28a1c8ba9023d804959c19dd601bc63b2dd9 Mon Sep 17 00:00:00 2001 From: Jens Rommel Date: Wed, 21 Aug 2013 16:28:09 +0200 Subject: [PATCH 041/227] Updated sailing webservices (markdown) --- wiki/sailing-webservices.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wiki/sailing-webservices.md b/wiki/sailing-webservices.md index acd9f92b7be..c2b9ee136bd 100644 --- a/wiki/sailing-webservices.md +++ b/wiki/sailing-webservices.md @@ -6,6 +6,9 @@ For all service URLs, please note that we use an Apache reverse proxy to map URL In all subsequent explanations, you may replace the "www.sapsailing.com" hostname by an according per-event host name to make sure you get to the event you're interested in. +## Webservice Documentation +http://www.sapsailing.com/sailingserver/webservices + ## Regatta Overview To get an overview of which regattas a server offers, use From 97e35b3dbbe584a27a65acc5b6867e69d76ac640 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Thu, 29 Aug 2013 09:48:56 +0200 Subject: [PATCH 042/227] Added event description for ESS Nice --- .../ess40/mobile.html | 9 +-- java/com.sap.sailing.www/index.html | 71 +++++++++---------- 2 files changed, 35 insertions(+), 45 deletions(-) diff --git a/java/com.sap.sailing.www.events/ess40/mobile.html b/java/com.sap.sailing.www.events/ess40/mobile.html index aec15c0dfd7..b1592476ea7 100644 --- a/java/com.sap.sailing.www.events/ess40/mobile.html +++ b/java/com.sap.sailing.www.events/ess40/mobile.html @@ -20,18 +20,11 @@

Extreme Sailing Series 2013

Next Event

- Act 6 - Cardiff, England -

-

- August 22th - 25th -

- +
From fc171a123f196f849a028e9ac5d1ffdc485c2eb3 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 19 Sep 2013 14:59:34 +0200 Subject: [PATCH 130/227] removed duplicate timeBar element --- java/com.sap.sailing.www/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/java/com.sap.sailing.www/index.html b/java/com.sap.sailing.www/index.html index 807bd1d0ad3..a66e67f377e 100644 --- a/java/com.sap.sailing.www/index.html +++ b/java/com.sap.sailing.www/index.html @@ -35,7 +35,6 @@

Live

-
From e8c0b33dca4b1239457c34c824b5d72646d307c5 Mon Sep 17 00:00:00 2001 From: Fredrik Teschke Date: Thu, 19 Sep 2013 15:24:56 +0200 Subject: [PATCH 131/227] added image for wiki --- wiki/images/load-racelog-tracked-race.png | Bin 0 -> 81072 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 wiki/images/load-racelog-tracked-race.png diff --git a/wiki/images/load-racelog-tracked-race.png b/wiki/images/load-racelog-tracked-race.png new file mode 100644 index 0000000000000000000000000000000000000000..3f7480a8acc6cef90705d3bddb90d6df662f2613 GIT binary patch literal 81072 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%0AoML);zgtpsq&6@%MdU+PUsNNDS_A@~MR5de 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 YFS)Cfn^JpQ?i%n?lvRV4NIwkvFIBT~`2YX_ literal 0 HcmV?d00001 From 5bcf0f61931a141964bcb881f31c3cab66faae0f Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 20 Sep 2013 09:42:56 +0200 Subject: [PATCH 132/227] renamed "obsolete" to "deprecated" for deprecated RaceLogIdentifier format --- .../domain/persistence/impl/DomainObjectFactoryImpl.java | 4 ++-- .../src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java | 2 +- .../sailing/domain/racelog/impl/RaceLogIdentifierImpl.java | 2 +- .../test/TestStoringAndRetrievingRaceLogInLeaderboards.java | 2 +- .../test/TestStoringAndRetrievingRaceLogInRegatta.java | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java index 5012cdb002a..a4a06acaee3 100755 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java @@ -1009,8 +1009,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(identifier.getIdentifier())); loadRaceLogEvents(result, query); - // query for obsolete events - query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(identifier.getObsoleteIdentifier())); + // query for events with deprecated identifier format + query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(identifier.getDeprecatedIdentifier())); loadRaceLogEvents(result, query); } catch (Throwable t) { // something went wrong during DB access; report, then use empty new race log diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java index 71b8b8d97db..b20e8651d9a 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java @@ -12,7 +12,7 @@ public interface RaceLogIdentifier extends Serializable { Triple getIdentifier(); - String getObsoleteIdentifier(); + String getDeprecatedIdentifier(); RaceLogIdentifierTemplate getTemplate(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/RaceLogIdentifierImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/RaceLogIdentifierImpl.java index 5f6a89214cc..e80b0bc4e01 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/RaceLogIdentifierImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/RaceLogIdentifierImpl.java @@ -26,7 +26,7 @@ public class RaceLogIdentifierImpl implements RaceLogIdentifier { } @Override - public String getObsoleteIdentifier() { + public String getDeprecatedIdentifier() { return String.format("%s.%s.%s", this.getTemplate().getParentObjectName(), this.getRaceColumnName(), diff --git a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingRaceLogInLeaderboards.java b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingRaceLogInLeaderboards.java index 6dcd0c00b0a..a1e19a65f7d 100644 --- a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingRaceLogInLeaderboards.java +++ b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingRaceLogInLeaderboards.java @@ -270,7 +270,7 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogFinishPositioningConfirmedEvent.class.getSimpleName()); DBObject raceLogResult = new BasicDBObject(); - raceLogResult.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceColumn.getRaceLogIdentifier(defaultFleet).getObsoleteIdentifier())); + raceLogResult.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceColumn.getRaceLogIdentifier(defaultFleet).getDeprecatedIdentifier())); raceLogResult.put(FieldNames.RACE_LOG_EVENT.name(), result); MongoObjectFactoryImpl factoryImpl = (MongoObjectFactoryImpl) mongoObjectFactory; diff --git a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingRaceLogInRegatta.java b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingRaceLogInRegatta.java index f33f723f6e3..6a610148cd9 100644 --- a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingRaceLogInRegatta.java +++ b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingRaceLogInRegatta.java @@ -337,7 +337,7 @@ public class TestStoringAndRetrievingRaceLogInRegatta extends RaceLogMongoDBTest result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogFinishPositioningConfirmedEvent.class.getSimpleName()); DBObject raceLogResult = new BasicDBObject(); - raceLogResult.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceColumn.getRaceLogIdentifier(fleet).getObsoleteIdentifier())); + raceLogResult.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceColumn.getRaceLogIdentifier(fleet).getDeprecatedIdentifier())); raceLogResult.put(FieldNames.RACE_LOG_EVENT.name(), result); MongoObjectFactoryImpl factoryImpl = (MongoObjectFactoryImpl) mongoObjectFactory; From 5ff3576978404e3f7d900f51b764d73fe1bb41b6 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 20 Sep 2013 09:58:45 +0200 Subject: [PATCH 133/227] setting user agent and accept HTTP request parameters for NOAA declination service requests; fixes declination tests --- .../src/com/sap/sailing/declination/impl/NOAAImporter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/NOAAImporter.java b/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/NOAAImporter.java index 17172360183..86fd5ac0043 100755 --- a/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/NOAAImporter.java +++ b/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/NOAAImporter.java @@ -59,6 +59,9 @@ public class NOAAImporter { URL url = new URL(QUERY_URL+"?lon1="+position.getLngDeg()+"&lat1="+position.getLatDeg()+"&startYear=" + calendar.get(Calendar.YEAR) + "&startMonth=" + (calendar.get(Calendar.MONTH) + 1) + "&startDay=" + calendar.get(Calendar.DAY_OF_MONTH)+"&resultFormat=xml"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); + conn.setRequestProperty("Accept-Language", "en-US,en;q=0.8"); + conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); final InputStream inputStream = conn.getInputStream(); Document doc = builder.parse(inputStream); From 2463bc49f2651f866bdb4aeb1506f9eb918ac8f6 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 20 Sep 2013 10:48:35 +0200 Subject: [PATCH 134/227] switch running product to port 8085 for Selenium tests; 8086 collides with Wowza's default port --- java/com.sap.sailing.selenium.test/ci-test-environment.xml | 2 +- java/com.sap.sailing.selenium.test/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.selenium.test/ci-test-environment.xml b/java/com.sap.sailing.selenium.test/ci-test-environment.xml index 2cb73ec5cf8..ea3299033c0 100644 --- a/java/com.sap.sailing.selenium.test/ci-test-environment.xml +++ b/java/com.sap.sailing.selenium.test/ci-test-environment.xml @@ -13,7 +13,7 @@ - http://riccardo:riccardo@localhost:8086/ + http://riccardo:riccardo@localhost:8085/ +

Upcoming

@@ -89,6 +68,29 @@

2013

+
@@ -432,3 +434,4 @@ + From d14029a845f0d857e6c2a51fa4016b0ac8fa03d2 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 24 Sep 2013 16:22:52 +0200 Subject: [PATCH 143/227] fixed date for Nice --- java/com.sap.sailing.www/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.www/index.html b/java/com.sap.sailing.www/index.html index 913cca56ab4..bda74b4dae7 100644 --- a/java/com.sap.sailing.www/index.html +++ b/java/com.sap.sailing.www/index.html @@ -44,7 +44,7 @@
- Sep 2 - 7 + Oct 3 - 6
From f29f20f103dd9a2675d8f2a5072eeb2bfcab44d4 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 24 Sep 2013 16:48:25 +0200 Subject: [PATCH 144/227] implemented the methods that help decide whether a score correction is to be considered valid at a given time point --- .../leaderboard/impl/ScoreCorrectionImpl.java | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java index 4f465538250..285a997b212 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java @@ -239,8 +239,44 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection { * earlier races. */ private boolean isCertainlyAfterRaceFinish(TimePoint timePoint, RaceColumn raceColumn, Competitor competitor) { - // TODO - return false; + final boolean result; + TrackedRace trackedRace = raceColumn.getTrackedRace(competitor); + final TimePoint endOfRace; + // endOfRace != null means we at least will have a fallback result even if there are no mark passings for the competitor + if (trackedRace != null && (endOfRace = trackedRace.getEndOfRace()) != null) { + NavigableSet markPassings = trackedRace.getMarkPassings(competitor); + final MarkPassing lastMarkPassing; + // count race as finished for the competitor if the finish mark passing exists or the time is after the end of race + if (!markPassings.isEmpty() && (lastMarkPassing = markPassings.last()).getWaypoint() == trackedRace.getRace().getCourse().getLastWaypoint()) { + result = timePoint.after(lastMarkPassing.getTimePoint()); + } else { + // if available, use the end of the race as indicator for how long competitor may have been in the race + result = timePoint.after(endOfRace); + } + } else { + boolean preResult = false; + boolean found = false; + for (RaceColumn rc : getLeaderboard().getRaceColumns()) { + if (!found && rc == raceColumn) { + found = true; + break; + } + if (found) { + TrackedRace rcTrackedRace = rc.getTrackedRace(competitor); + if (rcTrackedRace != null) { + // if available, use the start of the race as indicator for whether the competitor is in that + // race at timePoint + TimePoint startOfRace = rcTrackedRace.getStartOfRace(); + if (startOfRace != null && timePoint.after(startOfRace)) { + preResult = true; + break; + } + } + } + } + result = preResult; + } + return result; } @Override From 85b50ce4e214506d3c3f02eb76a0e2470f0880ca Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Tue, 24 Sep 2013 16:48:37 +0200 Subject: [PATCH 145/227] Showing Nice leaderboard --- java/com.sap.sailing.www.events/ess40/mobile.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.www.events/ess40/mobile.html b/java/com.sap.sailing.www.events/ess40/mobile.html index b1592476ea7..7c4b627b278 100644 --- a/java/com.sap.sailing.www.events/ess40/mobile.html +++ b/java/com.sap.sailing.www.events/ess40/mobile.html @@ -23,7 +23,7 @@ Act 7 - Nice, France

- September 2th - 6th + October 2th - 6th