java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/IgtimiDevicesPanel.java
... ...
@@ -20,6 +20,7 @@ import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
20 20
import com.google.gwt.user.cellview.client.TextColumn;
21 21
import com.google.gwt.user.client.Window;
22 22
import com.google.gwt.user.client.rpc.AsyncCallback;
23
+import com.google.gwt.user.client.ui.Anchor;
23 24
import com.google.gwt.user.client.ui.Button;
24 25
import com.google.gwt.user.client.ui.CaptionPanel;
25 26
import com.google.gwt.user.client.ui.FlowPanel;
... ...
@@ -40,6 +41,7 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
40 41
import com.sap.sailing.gwt.ui.shared.IgtimiDataAccessWindowWithSecurityDTO;
41 42
import com.sap.sailing.gwt.ui.shared.IgtimiDeviceWithSecurityDTO;
42 43
import com.sap.sse.common.Util;
44
+import com.sap.sse.common.Util.Pair;
43 45
import com.sap.sse.gwt.adminconsole.AdminConsoleTableResources;
44 46
import com.sap.sse.gwt.adminconsole.FilterablePanelProvider;
45 47
import com.sap.sse.gwt.client.ErrorReporter;
... ...
@@ -69,12 +71,7 @@ import com.sap.sse.security.ui.client.component.SecuredDTOOwnerColumn;
69 71
import com.sap.sse.security.ui.client.component.editacl.EditACLDialog;
70 72
71 73
/**
72
- * TODO bug 6059: implement a second table shown when a single device is selected in the devices table that shows the
73
- * data access windows for that device; alternatively we could show all data access windows for all devices when nothing
74
- * is selected. Move the "Add" button from devices to DAWs.
75
- *
76 74
* @author Axel Uhl (d043530)
77
- *
78 75
*/
79 76
public class IgtimiDevicesPanel extends FlowPanel implements FilterablePanelProvider<IgtimiDeviceWithSecurityDTO> {
80 77
private final StringMessages stringMessages;
... ...
@@ -113,6 +110,27 @@ public class IgtimiDevicesPanel extends FlowPanel implements FilterablePanelProv
113 110
this.errorReporter = presenter.getErrorReporter();
114 111
this.stringMessages = stringMessages;
115 112
final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
113
+ final Label igtimiConnectionFactoryParams = new Label();
114
+ final Anchor linkToRemoteRiotAdminPanel = new Anchor(stringMessages.configuration(), (String) null, /* target */ "_blank");
115
+ final HorizontalPanel remoteRiotConfig = new HorizontalPanel();
116
+ remoteRiotConfig.setSpacing(5);
117
+ remoteRiotConfig.add(igtimiConnectionFactoryParams);
118
+ remoteRiotConfig.add(linkToRemoteRiotAdminPanel);
119
+ add(remoteRiotConfig);
120
+ add(new Label(stringMessages.localServer()));
121
+ sailingServiceWrite.getIgtimiConnectionFactoryBaseUrl(new AsyncCallback<Pair<String, Boolean>>() {
122
+ @Override
123
+ public void onFailure(Throwable caught) {
124
+ Notification.notify(stringMessages.errorGettingIgtimiConnectionFactoryParams(caught.getMessage()), NotificationType.ERROR);
125
+ }
126
+
127
+ @Override
128
+ public void onSuccess(Pair<String, Boolean> result) {
129
+ igtimiConnectionFactoryParams.setText(stringMessages.igtimiConnectionFactoryParams(result.getA(),
130
+ result.getB() ? stringMessages.yes() : stringMessages.no()));
131
+ linkToRemoteRiotAdminPanel.setHref(result.getA()+"/gwt/AdminConsole.html#IgtimiDevicesPlace:");
132
+ }
133
+ });
116 134
// setup devices table
117 135
final CaptionPanel devicesCaptionPanel = new CaptionPanel(stringMessages.igtimiDevices());
118 136
final VerticalPanel devicesCaptionPanelContents = new VerticalPanel();
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java
... ...
@@ -493,7 +493,9 @@ public interface SailingService extends RemoteService, RemoteReplicationService
493 493
ArrayList<IgtimiDeviceWithSecurityDTO> getAllIgtimiDevicesWithSecurity() throws Exception;
494 494
495 495
ArrayList<IgtimiDataAccessWindowWithSecurityDTO> getAllIgtimiDataAccessWindowsWithSecurity() throws Exception;
496
-
496
+
497
+ Pair<String, Boolean> getIgtimiConnectionFactoryBaseUrl();
498
+
497 499
/**
498 500
* Allows reading public Boats, or Boats that are registered in races belonging in the given regatta
499 501
*/
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java
... ...
@@ -546,6 +546,8 @@ public interface SailingServiceAsync extends RemoteReplicationServiceAsync {
546 546
547 547
void getAllIgtimiDataAccessWindowsWithSecurity(AsyncCallback<ArrayList<IgtimiDataAccessWindowWithSecurityDTO>> callback);
548 548
549
+ void getIgtimiConnectionFactoryBaseUrl(AsyncCallback<Pair<String, Boolean>> callback);
550
+
549 551
/**
550 552
* Allows reading public Boats, or Boats that are registered in races belonging in the given regatta
551 553
*/
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
... ...
@@ -2472,4 +2472,6 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
2472 2472
String endOfRepeatablePartMustBeAtOfAfterStart();
2473 2473
String endOfRepeatablePartIsGreaterThanNumberOfWaypoints();
2474 2474
String configureCourse();
2475
+ String errorGettingIgtimiConnectionFactoryParams(String message);
2476
+ String igtimiConnectionFactoryParams(String baseUrl, String hasCredentialsYesOrNo);
2475 2477
}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
... ...
@@ -2508,4 +2508,6 @@ defaultNumberOfLapsMustNotBeNegative=Default number of laps must not be negative
2508 2508
eitherNoneOrBothStartAndEndOfRepeatablePartMustBeSpecified=Either none or both, start and end, of the repeatable part of the waypoint sequence must be specified.
2509 2509
endOfRepeatablePartMustBeAtOfAfterStart=End of repeatable part must be at or after start of repeatable part.
2510 2510
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=End of repeatable part is greater than number of waypoints.
2511
-configureCourse=Configure Course
... ...
\ No newline at end of file
0
+configureCourse=Configure Course
1
+errorGettingIgtimiConnectionFactoryParams=Error getting Igtimi connection factory parameters: {0}
2
+igtimiConnectionFactoryParams=Igtimi connection factory parameters: Base URL is {0}, credentials provided: {1}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
... ...
@@ -2502,4 +2502,6 @@ defaultNumberOfLapsMustNotBeNegative=Standard-Rundenzahl darf nicht negativ sein
2502 2502
eitherNoneOrBothStartAndEndOfRepeatablePartMustBeSpecified=Anfang und Ende der wiederholbaren Wegpunkte-Sequenz müssen entweder beide gesetzt oder beide leer sein.
2503 2503
endOfRepeatablePartMustBeAtOfAfterStart=Ende der wiederholbaren Wegpunkte-Sequenz muss auf oder nach dem Anfang liegen.
2504 2504
endOfRepeatablePartIsGreaterThanNumberOfWaypoints=Ende der wiederholbaren Wegpunkte-Sequenz liegt hinter dem Ende der Wegpunkt-Liste.
2505
-configureCourse=Kurs konfigurieren
... ...
\ No newline at end of file
0
+configureCourse=Kurs konfigurieren
1
+errorGettingIgtimiConnectionFactoryParams=Fehler beim Laden der Igtimi Verbindungsparameter: {0}
2
+igtimiConnectionFactoryParams=Igtimi Server: {0}, Benutzer-Authentifizierungsdaten vorhanden: {1}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java
... ...
@@ -4240,6 +4240,12 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
4240 4240
}
4241 4241
4242 4242
@Override
4243
+ public Pair<String, Boolean> getIgtimiConnectionFactoryBaseUrl() {
4244
+ final IgtimiConnectionFactory igtimiConnectionFactory = getIgtimiConnectionFactory();
4245
+ return new Pair<>(igtimiConnectionFactory.getBaseUrl().toString(), igtimiConnectionFactory.hasCredentials());
4246
+ }
4247
+
4248
+ @Override
4243 4249
public ArrayList<IgtimiDeviceWithSecurityDTO> getAllIgtimiDevicesWithSecurity() throws IllegalStateException, ClientProtocolException, IOException, org.json.simple.parser.ParseException {
4244 4250
final Map<String, TimePoint> lastHeartBeatsByDeviceSerialNumber = new HashMap<>();
4245 4251
final Map<String, SocketAddress> remoteAddressByDeviceSerialNumber = new HashMap<>();
java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/procedures/SailingProcessConfigurationVariables.java
... ...
@@ -14,5 +14,20 @@ public enum SailingProcessConfigurationVariables implements ProcessConfiguration
14 14
* a typical port would be 6000 which is the default for the WindBot devices. If not specified, the
15 15
* Riot server will listen on any available, unused server port. Maps to the igtimi.riot.port property.
16 16
*/
17
- IGTIMI_RIOT_PORT;
17
+ IGTIMI_RIOT_PORT,
18
+
19
+ /**
20
+ * Use this variable to override the default {@code https://wind.sapsailing.com} base URL for obtaining
21
+ * wind data from Igtimi devices. Authentication to this service by default will assume shared security
22
+ * and therefore shared user bases with shared access tokens. If this does not apply to your set-up,
23
+ * consider using {@link #IGTIMI_BEARER_TOKEN} in addition.
24
+ */
25
+ IGTIMI_BASE_URL,
26
+
27
+ /**
28
+ * Overrides the default authentication scheme for requests against the remote "Riot" service for Igtimi
29
+ * wind connectivity whose base URL may be overridden using {@link #IGTIMI_BASE_URL}. Specify a bearer token
30
+ * valid in the context of the security service of the remote Riot service.
31
+ */
32
+ IGTIMI_BEARER_TOKEN;
18 33
}
java/com.sap.sailing.www/release_notes_admin.html
... ...
@@ -35,14 +35,36 @@
35 35
environment variable set for the <tt>start</tt> script. When left empty,
36 36
the Riot server will listen on a random port unused so far. This port can
37 37
be obtained using the <tt>/igtimi/api/v1/server</tt> REST GET method, found
38
- in the <tt>port</tt> attribute of the JSON document responded with.<p>
38
+ in the <tt>port</tt> attribute of the JSON document responded with.
39
+ The built-in Riot server is replicated by default, and devices and data access
40
+ windows are kept synchronized between primary and replicas. Dedicated instances
41
+ may be set up with the only purpose of acting as a highly-available Riot server
42
+ farm. Messages sent to one of the instances in the replica set will make it to
43
+ all instances in the replica set and will eventually get stored persistently in
44
+ the primary's database.
45
+ <p>
39 46
Devices can be configured to send to that port, directly to the server's IP
40 47
address with the specific port, or, e.g., through a network load balancer
41 48
such as the Amazon Web Services (AWS) NLB, allowing for multiple servers
42 49
such as a primary/master and one or more replicas to be registered for
43 50
high availability. With an AWS NLB it is important to configure the target group
44 51
such that the client IP address is preserved, so the server knows where to send
45
- responses and commands to.<p>
52
+ responses and commands to.
53
+ <p>
54
+ Instead of managing Igtimi "Accounts" there now is a system property <tt>igtimi.base.url</tt>
55
+ that defines the base URL of the Riot service to which the Sailing Analytics server will
56
+ connect for live and stored WindBot data. The new environment variable <tt>IGTIMI_BASE_URL</tt>
57
+ is mapped to the <tt>igtimi.base.url</tt> property in the start scripts.
58
+ The property defaults to <tt>https://wind.sapsailing.com</tt>.
59
+ By default, authentication for the remote service is handled using the local user's bearer token
60
+ of the user tracking or owning the race for which wind data is requested. The <tt>igtimi.bearer.token</tt>
61
+ system property can be used as an override, e.g., in case the local Sailing Analytics server
62
+ does not share the security service with the replica set running the Riot service. The corresponding
63
+ environment variable is <tt>IGTIMI_BEARER_TOKEN</tt>. With this,
64
+ the <tt>igtimi.client.id</tt> and <tt>igtimi.client.secret</tt> system properties, as well as
65
+ their environment variable counterparts <tt>IGTIMI_CLIENT_ID</tt> and <tt>IGTIMI_CLIENT_SECRET</tt>,
66
+ respectively, are no longer used.
67
+ <p>
46 68
The new version of the Igtimi Devices panel in the Admin Console (see
47 69
<tt>/gwt/AdminConsole.html#IgtimiDevicesPlace:</tt>) now shows the devices
48 70
and their sharing to clients through so-called "Data Access Windows." The
... ...
@@ -52,7 +74,8 @@
52 74
the DAWs' ownership and access control list (ACL) settings and grant users
53 75
explicit permissions to individual DAWs. Click on the "Change Ownership" action icon
54 76
to see the key of a DAW in case you want to use it in an individual permission
55
- that you grant to a user.<p>
77
+ that you grant to a user.
78
+ <p>
56 79
There is a REST API that mimics the old Riot REST API to a certain degree.
57 80
Sailing Analytics users and operators typically don't work with this API directly.
58 81
Yet, the API is exposed under <tt>/igtimi/api/v1</tt> and has end points for
... ...
@@ -60,11 +83,13 @@
60 83
as well as for finding out the web socket server end
61 84
point for connecting to live data and connecting to it,
62 85
and the above-mentioned method for finding
63
- out the Riot server socket's listening port.<p>
86
+ out the Riot server socket's listening port.
87
+ <p>
64 88
The protocol used for transmitting device data to REST API clients has changed in
65 89
so far that the device message payloads are no longer sent as JSON objects; instead,
66 90
the original Protocol Buffer (protobuf) binary messages are encoded using Base64
67
- and transmitted as an array of such Base64 strings.</li>
91
+ and transmitted as an array of such Base64 strings.
92
+ </li>
68 93
</ul>
69 94
<h2 class="articleSubheadline">November 2024</h2>
70 95
<ul class="bulletList">
java/target/env-default-rules.sh
... ...
@@ -116,11 +116,11 @@ fi
116 116
if [ -n "${MANAGE2SAIL_ACCESS_TOKEN}" ]; then
117 117
ADDITIONAL_JAVA_ARGS="${ADDITIONAL_JAVA_ARGS} -Dmanage2sail.accesstoken=${MANAGE2SAIL_ACCESS_TOKEN}"
118 118
fi
119
-if [ -n "${IGTIMI_CLIENT_ID}" ]; then
120
- ADDITIONAL_JAVA_ARGS="${ADDITIONAL_JAVA_ARGS} -Digtimi.client.id=${IGTIMI_CLIENT_ID}"
119
+if [ -n "${IGTIMI_BASE_URL}" ]; then
120
+ ADDITIONAL_JAVA_ARGS="${ADDITIONAL_JAVA_ARGS} -Digtimi.base.url=${IGTIMI_BASE_URL}"
121 121
fi
122
-if [ -n "${IGTIMI_CLIENT_SECRET}" ]; then
123
- ADDITIONAL_JAVA_ARGS="${ADDITIONAL_JAVA_ARGS} -Digtimi.client.secret=${IGTIMI_CLIENT_SECRET}"
122
+if [ -n "${IGTIMI_BEARER_TOKEN}" ]; then
123
+ ADDITIONAL_JAVA_ARGS="${ADDITIONAL_JAVA_ARGS} -Digtimi.bearer.token=${IGTIMI_BEARER_TOKEN}"
124 124
fi
125 125
if [ -n "${GOOGLE_MAPS_AUTHENTICATION_PARAMS}" ]; then
126 126
ADDITIONAL_JAVA_ARGS="${ADDITIONAL_JAVA_ARGS} -Dgoogle.maps.authenticationparams=${GOOGLE_MAPS_AUTHENTICATION_PARAMS}"
wiki/howto/onboarding.md
... ...
@@ -116,7 +116,6 @@ Out of the box, multiple settings in Eclipse need to be changed. Go to Window
116 116
- In "General ⇒ Editors ⇒ Text Editors ⇒ Quick Diff" change the reference source from 'Version on Disk' to 'A Git Revision'. If you like other colours for marking diffs change them here. (Example: Changes = Yellow, Additions = Green, Deletions = Red)
117 117
- If you'd like to be able to import official results from the Manage2Sail regatta management system: In Run/Debug ⇒ String Substitution add a variable ``MANAGE2SAIL_ACCESS_TOKEN``. Ask your team lead for the value of such an access token you can uses for testing. The variable is used by the "Sailing Server (No Proxy)" launch configuration. and maybe others.
118 118
- For Google Maps API access, the server needs to know authentication parameters. These are provided through an Eclipse variable used by various launch configurations named ``GOOGLE_MAPS_AUTHENTICATION_PARAMS``. Ask for the official SAP Google Maps API credentials, or use ``key=AIzaSyD1Se4tIkt-wglccbco3S7twaHiG20hR9E`` for a test key that works for your localhost-based tests.
119
-- If you'd like to work with the Igtimi YachtBot / WindBot API, you'll have to provide two additional Eclipse variables: ``IGTIMI_CLIENT_ID`` and ``IGTIMI_CLIENT_SECRET``. Again, ask your team lead for those official credentials or, if you have administrative permissions to our production landscape, look them up under each sailing-analytics-server instance's ``/root/secrets`` file.
120 119
- In "GWT ⇒ Errors/Warnings" set "Missing SDK" to "Ignore"
121 120
- In "GWT ⇒ GWT Settings ⇒ Add..." add the GWT SDK you downloaded and unpacked earlier
122 121
- In "Java ⇒ Build Path ⇒ Classpath Variables" create a new classpath variable called `ANDROID_HOME`. Set its value to the installation location of your Android SDK, e.g., `C:\Users\'user'\AppData\Local\Android\Sdk` or `/usr/local/android-sdk-linux`.