From bd595d7809ace7176cc849e0830e47bf7ce7b913 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 20 Oct 2021 15:28:31 +0200 Subject: [PATCH] bug5628: include username/password in URL construction for YB API --- .../impl/YellowBrickAdapterTest.java | 12 ++++-- .../YellowBrickTrackingAdapter.java | 9 ++++- .../impl/YellowBrickTrackingAdapterImpl.java | 39 +++++++++++++++---- .../gwt/ui/server/SailingServiceImpl.java | 3 +- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/java/com.sap.sailing.domain.yellowbrickadapter.test/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickAdapterTest.java b/java/com.sap.sailing.domain.yellowbrickadapter.test/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickAdapterTest.java index 9e0e702fa30..d868c194c46 100755 --- a/java/com.sap.sailing.domain.yellowbrickadapter.test/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickAdapterTest.java +++ b/java/com.sap.sailing.domain.yellowbrickadapter.test/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickAdapterTest.java @@ -1,10 +1,12 @@ package com.sap.sailing.domain.yellowbrickadapter.impl; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.net.MalformedURLException; import java.text.SimpleDateFormat; +import java.util.Optional; import org.json.simple.parser.ParseException; import org.junit.Before; @@ -25,13 +27,15 @@ public class YellowBrickAdapterTest { @Test public void testSimpleUrlConstruction() { - final String rmsr2019Url = adapter.getUrlForLatestFix(RMSR2019); - assertEquals("https://yb.tl/API3/Race/rmsr2019/GetPositions?n=1", rmsr2019Url); + final String rmsr2019Url = adapter.getUrlForLatestFix(RMSR2019, /* username */ Optional.of("hello"), /* password */ Optional.of("world")); + assertTrue(rmsr2019Url.startsWith("https://yb.tl/API3/Race/rmsr2019/GetPositions?")); + assertTrue(rmsr2019Url.contains("username=hello")); + assertTrue(rmsr2019Url.contains("password=world")); } @Test public void testGetRaceMetadata() throws IOException, ParseException, java.text.ParseException { - final YellowBrickRace race = adapter.getRaceMetadata(RMSR2019); + final YellowBrickRace race = adapter.getRaceMetadata(RMSR2019, Optional.empty(), Optional.empty()); assertEquals(RMSR2019, race.getRaceUrl()); assertEquals(TimePoint.of(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse("2019-10-26T23:55:01Z")), race.getTimePointOfLastFix()); assertEquals(113, race.getNumberOfCompetitors()); @@ -39,7 +43,7 @@ public class YellowBrickAdapterTest { @Test public void testGetFullRaceData() throws MalformedURLException, IOException, ParseException, java.text.ParseException { - final PositionsDocument fullRace = adapter.getStoredData(RMSR2019); + final PositionsDocument fullRace = adapter.getStoredData(RMSR2019, /* username */ Optional.empty(), /* password */ Optional.empty()); assertEquals(113, Util.size(fullRace.getTeams())); assertEquals(TimePoint.of(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse("2019-10-26T23:55:01Z")), fullRace.getTimePointOfLastFix()); assertEquals(2009, Util.size(Util.filter(fullRace.getTeams(), team->team.getCompetitorName().equals("JYS Jarhead")).iterator().next().getPositions())); diff --git a/java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/YellowBrickTrackingAdapter.java b/java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/YellowBrickTrackingAdapter.java index ef19c02e56e..684acb12cde 100755 --- a/java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/YellowBrickTrackingAdapter.java +++ b/java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/YellowBrickTrackingAdapter.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.yellowbrickadapter; import java.io.IOException; import java.net.MalformedURLException; +import java.util.Optional; import org.json.simple.parser.ParseException; @@ -34,11 +35,15 @@ public interface YellowBrickTrackingAdapter { /** * Obtains the meta-data for the YellowBrick race identified by URL {@code raceUrl} + * @param username TODO + * @param password TODO */ - YellowBrickRace getRaceMetadata(String raceUrl) throws IOException, ParseException; + YellowBrickRace getRaceMetadata(String raceUrl, Optional username, Optional password) throws IOException, ParseException; /** * Retrieves all data stored for the race with {@code raceUrl} so far. + * @param username TODO + * @param password TODO */ - PositionsDocument getStoredData(String raceUrl) throws MalformedURLException, IOException, ParseException; + PositionsDocument getStoredData(String raceUrl, Optional username, Optional password) throws MalformedURLException, IOException, ParseException; } diff --git a/java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickTrackingAdapterImpl.java b/java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickTrackingAdapterImpl.java index 9db9e972e81..b1429772896 100755 --- a/java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickTrackingAdapterImpl.java +++ b/java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickTrackingAdapterImpl.java @@ -3,11 +3,14 @@ package com.sap.sailing.domain.yellowbrickadapter.impl; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; +import java.net.URLEncoder; import java.util.Collections; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -79,17 +82,37 @@ public class YellowBrickTrackingAdapterImpl implements YellowBrickTrackingAdapte /* timeout */ TIMEOUT_FOR_RACE_LOADING.asMillis()); } - String getUrlForLatestFix(String raceUrl) { - return String.format(NUMBER_OF_POSITIONS_URL_TEMPLATE, raceUrl, 1); + String getUrlForLatestFix(String raceUrl, Optional username, Optional password) { + return appendUsernameAndPasswordParameters(String.format(NUMBER_OF_POSITIONS_URL_TEMPLATE, raceUrl, 1), username, password); } - String getUrlForAllData(String raceUrl) { - return String.format(POSITIONS_SINCE_DATE_URL_TEMPLATE, raceUrl, /* since the beginning of the epoch */ 0l); + private String appendUsernameAndPasswordParameters(String url, Optional username, Optional password) { + final StringBuilder sb = new StringBuilder(url); + appendOptionalParameter(sb, "username", username); + appendOptionalParameter(sb, "password", password); + return sb.toString(); + } + + private void appendOptionalParameter(StringBuilder urlBuilder, String parameterName, Optional parameterValue) { + if (parameterValue.isPresent() && Util.hasLength(parameterValue.get())) { + urlBuilder.append("&"); + urlBuilder.append(parameterName); + urlBuilder.append("="); + try { + urlBuilder.append(URLEncoder.encode(parameterValue.get(), "UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + } + + String getUrlForAllData(String raceUrl, Optional username, Optional password) { + return appendUsernameAndPasswordParameters(String.format(POSITIONS_SINCE_DATE_URL_TEMPLATE, raceUrl, /* since the beginning of the epoch */ 0l), username, password); } @Override - public YellowBrickRace getRaceMetadata(String raceUrl) throws IOException, ParseException { - final String url = getUrlForLatestFix(raceUrl); + public YellowBrickRace getRaceMetadata(String raceUrl, Optional username, Optional password) throws IOException, ParseException { + final String url = getUrlForLatestFix(raceUrl, username, password); final PositionsDocument doc = getPositionsDocumentForUrl(url); return new YellowBrickRaceImpl(raceUrl, doc.getTimePointOfLastFix(), Util.size(doc.getTeams())); } @@ -103,8 +126,8 @@ public class YellowBrickTrackingAdapterImpl implements YellowBrickTrackingAdapte } @Override - public PositionsDocument getStoredData(String raceUrl) throws MalformedURLException, IOException, ParseException { - return getPositionsDocumentForUrl(getUrlForAllData(raceUrl)); + public PositionsDocument getStoredData(String raceUrl, Optional username, Optional password) throws MalformedURLException, IOException, ParseException { + return getPositionsDocumentForUrl(getUrlForAllData(raceUrl, username, password)); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 66b96ba1fe8..eb6bb24cb7a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -6310,7 +6310,8 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet @Override public Pair> listYellowBrickRacesInEvent(YellowBrickConfigurationWithSecurityDTO config) throws Exception { - final YellowBrickRace raceMetadata = getYellowBrickTrackingAdapter().getRaceMetadata(config.getRaceUrl()); + final YellowBrickRace raceMetadata = getYellowBrickTrackingAdapter().getRaceMetadata(config.getRaceUrl(), + Optional.ofNullable(config.getUsername()), Optional.ofNullable(config.getPassword())); return new Pair<>(raceMetadata.getRaceUrl(), Collections.singletonList(new YellowBrickRaceRecordDTO(config.getName(), raceMetadata.getRaceUrl(), hasRememberedRegatta(raceMetadata.getRaceId()),