mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-02 01:00:46 +00:00
bug6319: remove dead includeInvalid search parameter; export ORC_API_KEY
The key-based sas.orc.org API routes all active-certificate search through the activecerts endpoint, which returns active certificates only. The includeInvalid flag on ORCPublicCertificateDatabase.search(...) could therefore never change the result and was dead. Remove it from the interface and impl, the default getCertificateHandle, the two fuzzy-search call sites, SailingServiceImpl, and all ORC test call sites. The sole route to an inactive certificate in this adapter is to download it by reference number via DownBoatRMS_byrefno (getCertificate / getCertificateHandle); the search Javadoc now states this explicitly. Also export ORC_API_KEY from java/target/env-default-rules.sh so the Java VM can read it via System.getenv(...). configuration/secrets assigns it as a plain (non-exported) shell variable that the java child process would not otherwise inherit; it is passed as an environment variable rather than a -D system property so it is not exposed on the process command line. Assisted-By: Claude Opus 4.8 (claude-opus-5-5)
This commit is contained in:
1 parent
fd97a6b8a2
commit
85ccfc4e5e
9 files changed
+287
-113
No files matched your search
@@ -24,7 +24,7 @@ Export-Package: com.sap.sailing.domain.base,
|
||||
com.sap.sailing.domain.markpassinghash.impl;x-friends:="com.sap.sailing.domain.persistence",
|
||||
com.sap.sailing.domain.masterdataimport,
|
||||
com.sap.sailing.domain.orc,
|
||||
com.sap.sailing.domain.orc.impl;x-friends:="com.sap.sailing.domain.test,com.sap.sailing.domain.test,com.sap.sailing.mongodb.test",
|
||||
com.sap.sailing.domain.orc.impl;x-friends:="com.sap.sailing.domain.test,com.sap.sailing.mongodb.test",
|
||||
com.sap.sailing.domain.polars,
|
||||
com.sap.sailing.domain.racelog,
|
||||
com.sap.sailing.domain.racelog.impl,
|
||||
|
||||
+17
-15
@@ -22,10 +22,9 @@ import com.sap.sse.common.Util;
|
||||
* (see {@code https://sas.orc.org/api-docs.php}). It can search for certificates by a number of criteria, among them
|
||||
* the issuing country, sail number, ORC reference number, or boat name. Those search results are represented as
|
||||
* {@link CertificateHandle} objects, obtained from the {@code activecerts} endpoint through the
|
||||
* {@link #search(CountryCode, Integer, String, String, String, String, boolean)} method. The {@code includeInvalid}
|
||||
* parameter is retained for API compatibility; the {@code activecerts} endpoint returns active (valid) certificates
|
||||
* only, so every handle returned is {@link CertificateHandle#isValid() valid} and resolvable into a full
|
||||
* {@link ORCCertificate} via {@link #getCertificate(String, CertificateFamily)} (which uses the
|
||||
* {@link #search(CountryCode, Integer, String, String, String, String)} method. The {@code activecerts} endpoint
|
||||
* returns active (valid) certificates only, so every handle returned is {@link CertificateHandle#isValid() valid} and
|
||||
* resolvable into a full {@link ORCCertificate} via {@link #getCertificate(String, CertificateFamily)} (which uses the
|
||||
* {@code DownBoatRMS_byrefno} endpoint) or {@link #getCertificates(Iterable)}.
|
||||
* <p>
|
||||
* The per-country/family overview including the certificate counts and VPP years is obtained from the {@code RMS}
|
||||
@@ -205,19 +204,22 @@ public interface ORCPublicCertificateDatabase {
|
||||
* results based on that criterion. You can use "%" as wildcards in the {@code yachtName}, {@code sailNumber} and
|
||||
* {@code boatClassName} parameters.
|
||||
* <p>
|
||||
*
|
||||
* @param includeInvalid
|
||||
* If {@code true}, handles may have {@link CertificateHandle#isValid()}{@code == false}, meaning that
|
||||
* such a handle cannot be resolved to a {@link ORCCertificate} using any of
|
||||
* {@link #getCertificate(String)}, {@link #getCertificates(Iterable)} and
|
||||
* {@link #getCertificates(CertificateHandle...)}. If {@code false}, only valid certificate handles
|
||||
* will be returned that should all be resolvable into an {@link ORCCertificate} with any of the methods
|
||||
* listed above.
|
||||
*
|
||||
* This search runs against the {@code activecerts} endpoint and therefore returns <em>currently active
|
||||
* certificates only</em>; inactive, expired or superseded certificates are never returned, regardless of the
|
||||
* criteria. In particular, searching by {@code referenceNumber} here will <em>not</em> find an inactive
|
||||
* certificate even though the reference number identifies it exactly. The only way this adapter reaches an
|
||||
* inactive certificate is to download it by its reference number through
|
||||
* {@link #getCertificate(String, CertificateFamily)} (backed by the {@code DownBoatRMS_byrefno} endpoint, which
|
||||
* serves a certificate whether or not it is still active); {@link #getCertificateHandle(String)} does the same to
|
||||
* obtain a {@link CertificateHandle}. There is no search over inactive certificates in this adapter. Every handle
|
||||
* returned by this method is {@link CertificateHandle#isValid() valid} and resolvable into an
|
||||
* {@link ORCCertificate} via {@link #getCertificate(String, CertificateFamily)} or
|
||||
* {@link #getCertificates(Iterable)}.
|
||||
*
|
||||
* @return never {@code null}; an object which may be {@link Util#isEmpty() empty}.
|
||||
*/
|
||||
Iterable<CertificateHandle> search(CountryCode country, Integer yearOfIssuance, String referenceNumber,
|
||||
String yachtName, String sailNumber, String boatClassName, boolean includeInvalid) throws Exception;
|
||||
String yachtName, String sailNumber, String boatClassName) throws Exception;
|
||||
|
||||
Iterable<ORCCertificate> getCertificates(Iterable<CertificateHandle> handles) throws Exception;
|
||||
|
||||
@@ -226,7 +228,7 @@ public interface ORCPublicCertificateDatabase {
|
||||
}
|
||||
|
||||
default CertificateHandle getCertificateHandle(String referenceNumber) throws Exception {
|
||||
return search(null, null, referenceNumber, null, null, null, /* includeInvalid */ true).iterator().next();
|
||||
return search(null, null, referenceNumber, null, null, null).iterator().next();
|
||||
}
|
||||
|
||||
ORCCertificate searchForUpdate(ORCCertificate certificate) throws Exception;
|
||||
|
||||
+40
-4
@@ -79,6 +79,7 @@ public class ORCPublicCertificateDatabaseImpl implements ORCPublicCertificateDat
|
||||
private static final String ENDPOINT_ACTIVECERTS = "activecerts";
|
||||
private static final String ENDPOINT_RMS = "RMS";
|
||||
private static final String ENDPOINT_DOWNBOATRMS_BYREFNO = "DownBoatRMS_byrefno";
|
||||
private static final String ENDPOINT_DOWNRMS = "DownRMS";
|
||||
private static final String EXT_JSON = "ext=json";
|
||||
|
||||
private static final String DATA_KEY = "data";
|
||||
@@ -352,8 +353,7 @@ public class ORCPublicCertificateDatabaseImpl implements ORCPublicCertificateDat
|
||||
|
||||
@Override
|
||||
public Iterable<CertificateHandle> search(final CountryCode issuingCountry, final Integer yearOfIssuance,
|
||||
final String referenceNumber, final String yachtName, final String sailNumber, final String boatClassName,
|
||||
final boolean includeInvalid /* retained for API compatibility; activecerts returns valid certs only */)
|
||||
final String referenceNumber, final String yachtName, final String sailNumber, final String boatClassName)
|
||||
throws IOException {
|
||||
final Set<CertificateHandle> result = new HashSet<>();
|
||||
final List<String> queryParts = new ArrayList<>();
|
||||
@@ -418,6 +418,29 @@ public class ORCPublicCertificateDatabaseImpl implements ORCPublicCertificateDat
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a certificate handle directly from its reference number through the {@code DownBoatRMS_byrefno} download
|
||||
* endpoint rather than through the active-certificate {@link #search(CountryCode, Integer, String, String, String,
|
||||
* String, boolean) search}. The {@code activecerts} search only ever returns currently active certificates, whereas
|
||||
* this endpoint also serves inactive/expired certificates, so this override preserves the pre-key-API behavior that
|
||||
* a handle could be obtained for any certificate addressable by its reference number. Returns {@code null} if no
|
||||
* certificate exists for the given reference number.
|
||||
*/
|
||||
@Override
|
||||
public CertificateHandle getCertificateHandle(final String referenceNumber) throws IOException {
|
||||
final ORCCertificate certificate = getCertificate(referenceNumber, CertificateFamily.UNKNOWN);
|
||||
return certificate == null ? null : handleFromCertificate(certificate);
|
||||
}
|
||||
|
||||
private CertificateHandle handleFromCertificate(final ORCCertificate certificate) {
|
||||
final Double gph = certificate.getGPH() == null ? null : certificate.getGPH().asSeconds();
|
||||
return new CertificateHandleImpl(certificate.getIssuingCountry(), certificate.getFileId(), gph,
|
||||
/* sssid */ null, /* datInGID */ null, certificate.getReferenceNumber(), CertificateFamily.UNKNOWN,
|
||||
certificate.getBoatName(), certificate.getSailNumber(), certificate.getBoatClassName(),
|
||||
/* designer */ null, /* builder */ null, /* yearBuilt */ null, certificate.getIssueDate(),
|
||||
/* certType */ null, /* oneDesign */ null, /* isProvisional */ Boolean.FALSE, /* isValid */ Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ORCCertificate searchForUpdate(final CertificateHandle certificateHandle) throws IOException {
|
||||
return searchForUpdate(certificateHandle.getReferenceNumber());
|
||||
@@ -457,6 +480,19 @@ public class ORCPublicCertificateDatabaseImpl implements ORCPublicCertificateDat
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a stream on the bulk per-country certificate download provided by the {@code DownRMS} endpoint for the
|
||||
* given {@code country}, in the JSON format consumed by {@link ORCCertificatesJsonImporter#read(InputStream)}. All
|
||||
* endpoint knowledge (base URL, endpoint name, {@code ext} parameter) and the API key live in this implementation
|
||||
* only; the key is read from the {@value #API_KEY_ENV_VARIABLE_NAME} environment variable and never logged. This
|
||||
* method is exported to the test bundle via an {@code x-friends} restriction so that tests can obtain the online
|
||||
* bulk stream without duplicating the URL construction or the key handling.
|
||||
*/
|
||||
public InputStream openBulkCertificatesJsonStream(final CountryCode country) throws IOException {
|
||||
return httpGetStream(endpointUrl(requireApiKey(), ENDPOINT_DOWNRMS,
|
||||
KEY_COUNTRY_ID + "=" + encode(country.getThreeLetterIOCCode()) + "&" + EXT_JSON));
|
||||
}
|
||||
|
||||
private CertificateHandle parseHandleFromActiveCertRow(final JSONObject row) throws DateTimeParseException {
|
||||
final CountryCode issuingCountry = countryFromIoc(asTrimmedString(row.get(KEY_COUNTRY_ID)));
|
||||
final String dxtName = asString(row.get(KEY_DXT_NAME));
|
||||
@@ -723,13 +759,13 @@ public class ORCPublicCertificateDatabaseImpl implements ORCPublicCertificateDat
|
||||
*/
|
||||
private Iterable<CertificateHandle> fuzzySearchVaryingBoatClassName(final String yachtName, final String sailNumber, final BoatClass boatClass) throws Exception {
|
||||
String successfulBoatClassName = boatClass==null?null:boatClass.getName();
|
||||
Iterable<CertificateHandle> certificateHandles = search(/* issuingCountry */ null, /* yearOfIssuance */ null, /* referenceNumber */ null, yachtName, sailNumber, successfulBoatClassName, /* includeInvalid */ false);
|
||||
Iterable<CertificateHandle> certificateHandles = search(/* issuingCountry */ null, /* yearOfIssuance */ null, /* referenceNumber */ null, yachtName, sailNumber, successfulBoatClassName);
|
||||
if (!containsValidHandle(certificateHandles) && successfulBoatClassName != null) {
|
||||
if (yachtName != null || sailNumber != null) {
|
||||
logger.fine(()->"Nothing found; removing boat class name restriction "+boatClass.getName());
|
||||
// try without boat class restriction
|
||||
successfulBoatClassName = null;
|
||||
certificateHandles = search(/* issuingCountry */ null, /* yearOfIssuance */ null, /* referenceNumber */ null, yachtName, sailNumber, successfulBoatClassName, /* includeInvalid */ false);
|
||||
certificateHandles = search(/* issuingCountry */ null, /* yearOfIssuance */ null, /* referenceNumber */ null, yachtName, sailNumber, successfulBoatClassName);
|
||||
} else {
|
||||
logger.fine(()->"No current certificates found for boat class "+boatClass.getName()+
|
||||
" but yacht name and sail number are not specified either; giving up.");
|
||||
|
||||
Reference in new issue
Block a user