This is an automated email from the ASF dual-hosted git repository. cstamas pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-indexer.git
The following commit(s) were added to refs/heads/master by this push: new aaf9623 [MINDEXER-254] Add CSC, add hacks circumventing CSC bug and make project more open (#425) aaf9623 is described below commit aaf962303de22a86a4d47186aacc51e198d795f3 Author: Tamas Cservenak <ta...@cservenak.net> AuthorDate: Fri May 30 19:04:00 2025 +0200 [MINDEXER-254] Add CSC, add hacks circumventing CSC bug and make project more open (#425) Adds CSC support, with a hack to support CSC bug re paging. On related note, make whole Search API more open and "hackable", that is more accessible for client code. --- https://issues.apache.org/jira/browse/MINDEXER-253 https://issues.apache.org/jira/browse/MINDEXER-254 --- indexer-examples/indexer-examples-spring/pom.xml | 2 +- .../java/org/apache/maven/search/api/Record.java | 12 +- .../org/apache/maven/search/api/SearchRequest.java | 6 +- .../maven/search/api/request/BooleanQuery.java | 8 +- .../org/apache/maven/search/api/request/Field.java | 4 +- .../maven/search/api/request/FieldQuery.java | 2 +- .../apache/maven/search/api/request/Paging.java | 6 +- .../org/apache/maven/search/api/request/Query.java | 2 +- .../search/api/support/SearchBackendSupport.java | 4 +- .../search/api/support/SearchResponseSupport.java | 6 +- .../api/transport/Java11HttpClientTransport.java | 12 +- .../search/backend/remoterepository/Context.java | 8 +- .../backend/remoterepository/RecordFactory.java | 6 +- .../extractor/MavenCentralResponseExtractor.java | 2 +- .../extractor/Nx2ResponseExtractor.java | 2 +- .../RemoteRepositorySearchBackendImpl.java | 14 +-- .../RemoteRepositorySearchResponseImpl.java | 4 +- .../backend/smo/SmoSearchBackendFactory.java | 47 ++++++- .../backend/smo/internal/SmoSearchBackendImpl.java | 68 ++++++---- .../smo/internal/SmoSearchResponseImpl.java | 4 +- .../smo/internal/CscSearchBackendImplTest.java} | 22 ++-- .../smo/internal/SmoSearchBackendImplTest.java | 140 +-------------------- ...lTest.java => SmoSearchBackendTestSupport.java} | 15 +-- 23 files changed, 161 insertions(+), 235 deletions(-) diff --git a/indexer-examples/indexer-examples-spring/pom.xml b/indexer-examples/indexer-examples-spring/pom.xml index ec80bf8..97cc893 100644 --- a/indexer-examples/indexer-examples-spring/pom.xml +++ b/indexer-examples/indexer-examples-spring/pom.xml @@ -33,7 +33,7 @@ under the License. <description>This module contains Maven Indexer usage examples for integration with Spring.</description> <properties> - <version.spring>5.3.31</version.spring> + <version.spring>5.3.39</version.spring> </properties> <dependencies> diff --git a/search-api/src/main/java/org/apache/maven/search/api/Record.java b/search-api/src/main/java/org/apache/maven/search/api/Record.java index 53856eb..16b2eef 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/Record.java +++ b/search-api/src/main/java/org/apache/maven/search/api/Record.java @@ -29,16 +29,16 @@ import static java.util.Objects.requireNonNull; /** * A search response record. */ -public final class Record { - private final String backendId; +public class Record { + protected final String backendId; - private final String repositoryId; + protected final String repositoryId; - private final String uid; + protected final String uid; - private final Long lastUpdated; + protected final Long lastUpdated; - private final Map<Field, Object> fields; + protected final Map<Field, Object> fields; public Record(String backendId, String repositoryId, String uid, Long lastUpdated, Map<Field, Object> fields) { this.backendId = requireNonNull(backendId); diff --git a/search-api/src/main/java/org/apache/maven/search/api/SearchRequest.java b/search-api/src/main/java/org/apache/maven/search/api/SearchRequest.java index 64f50da..5f93319 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/SearchRequest.java +++ b/search-api/src/main/java/org/apache/maven/search/api/SearchRequest.java @@ -26,10 +26,10 @@ import static java.util.Objects.requireNonNull; /** * A search request to perform search: defines paging and query. */ -public final class SearchRequest { - private final Paging paging; +public class SearchRequest { + protected final Paging paging; - private final Query query; + protected final Query query; /** * Creates a request with given {@link Query} instance and default page size of 50. diff --git a/search-api/src/main/java/org/apache/maven/search/api/request/BooleanQuery.java b/search-api/src/main/java/org/apache/maven/search/api/request/BooleanQuery.java index eed6388..f2038e1 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/request/BooleanQuery.java +++ b/search-api/src/main/java/org/apache/maven/search/api/request/BooleanQuery.java @@ -24,9 +24,9 @@ import static java.util.Objects.requireNonNull; * Boolean query. */ public abstract class BooleanQuery extends Query { - private final Query left; + protected final Query left; - private final Query right; + protected final Query right; protected BooleanQuery(Query left, String op, Query right) { super(op); @@ -53,8 +53,8 @@ public abstract class BooleanQuery extends Query { return getLeft() + " " + getValue() + " " + getRight(); } - public static final class And extends BooleanQuery { - private And(Query left, Query right) { + public static class And extends BooleanQuery { + protected And(Query left, Query right) { super(left, "AND", right); } } diff --git a/search-api/src/main/java/org/apache/maven/search/api/request/Field.java b/search-api/src/main/java/org/apache/maven/search/api/request/Field.java index 35cf31c..fe47c75 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/request/Field.java +++ b/search-api/src/main/java/org/apache/maven/search/api/request/Field.java @@ -28,9 +28,9 @@ import static java.util.Objects.requireNonNull; * Field, that is used as key in record. */ public abstract class Field { - private final String fieldName; + protected final String fieldName; - private Field(String fieldName) { + protected Field(String fieldName) { this.fieldName = requireNonNull(fieldName); } diff --git a/search-api/src/main/java/org/apache/maven/search/api/request/FieldQuery.java b/search-api/src/main/java/org/apache/maven/search/api/request/FieldQuery.java index f108142..906edba 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/request/FieldQuery.java +++ b/search-api/src/main/java/org/apache/maven/search/api/request/FieldQuery.java @@ -24,7 +24,7 @@ import static java.util.Objects.requireNonNull; * Field query. */ public class FieldQuery extends Query { - private final Field field; + protected final Field field; protected FieldQuery(Field field, String queryString) { super(queryString); diff --git a/search-api/src/main/java/org/apache/maven/search/api/request/Paging.java b/search-api/src/main/java/org/apache/maven/search/api/request/Paging.java index 6a60de5..f8f611d 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/request/Paging.java +++ b/search-api/src/main/java/org/apache/maven/search/api/request/Paging.java @@ -21,10 +21,10 @@ package org.apache.maven.search.api.request; /** * Paging. */ -public final class Paging { - private final int pageSize; +public class Paging { + protected final int pageSize; - private final int pageOffset; + protected final int pageOffset; /** * Creates paging instance with given page size (must be greater than 0) and page offset (must be non-negative). diff --git a/search-api/src/main/java/org/apache/maven/search/api/request/Query.java b/search-api/src/main/java/org/apache/maven/search/api/request/Query.java index 1a0dcc2..b13e7aa 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/request/Query.java +++ b/search-api/src/main/java/org/apache/maven/search/api/request/Query.java @@ -24,7 +24,7 @@ import static java.util.Objects.requireNonNull; * Query. */ public class Query { - private final String queryString; + protected final String queryString; protected Query(String queryString) { this.queryString = requireNonNull(queryString); diff --git a/search-api/src/main/java/org/apache/maven/search/api/support/SearchBackendSupport.java b/search-api/src/main/java/org/apache/maven/search/api/support/SearchBackendSupport.java index a306a8f..e2dddce 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/support/SearchBackendSupport.java +++ b/search-api/src/main/java/org/apache/maven/search/api/support/SearchBackendSupport.java @@ -26,9 +26,9 @@ import static java.util.Objects.requireNonNull; * A search backend support class. */ public abstract class SearchBackendSupport implements SearchBackend { - private final String backendId; + protected final String backendId; - private final String repositoryId; + protected final String repositoryId; protected SearchBackendSupport(String backendId, String repositoryId) { this.backendId = requireNonNull(backendId); diff --git a/search-api/src/main/java/org/apache/maven/search/api/support/SearchResponseSupport.java b/search-api/src/main/java/org/apache/maven/search/api/support/SearchResponseSupport.java index 18317fb..0b30ecc 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/support/SearchResponseSupport.java +++ b/search-api/src/main/java/org/apache/maven/search/api/support/SearchResponseSupport.java @@ -30,11 +30,11 @@ import static java.util.Objects.requireNonNull; * A search response support class. */ public abstract class SearchResponseSupport implements SearchResponse { - private final SearchRequest searchRequest; + protected final SearchRequest searchRequest; - private final int totalHits; + protected final int totalHits; - private final List<Record> page; + protected final List<Record> page; protected SearchResponseSupport(SearchRequest searchRequest, int totalHits, List<Record> page) { this.searchRequest = requireNonNull(searchRequest); diff --git a/search-api/src/main/java/org/apache/maven/search/api/transport/Java11HttpClientTransport.java b/search-api/src/main/java/org/apache/maven/search/api/transport/Java11HttpClientTransport.java index 01c47cd..610b47d 100644 --- a/search-api/src/main/java/org/apache/maven/search/api/transport/Java11HttpClientTransport.java +++ b/search-api/src/main/java/org/apache/maven/search/api/transport/Java11HttpClientTransport.java @@ -35,13 +35,13 @@ import static java.util.Objects.requireNonNull; * Java 11 {@link HttpClient} backed transport. */ public class Java11HttpClientTransport implements Transport { - private static class ResponseImpl implements Response { + protected static class ResponseImpl implements Response { - private final HttpResponse<?> response; + protected final HttpResponse<?> response; - private final InputStream inputStream; + protected final InputStream inputStream; - private ResponseImpl(HttpResponse<?> response, InputStream inputStream) { + protected ResponseImpl(HttpResponse<?> response, InputStream inputStream) { this.response = requireNonNull(response); this.inputStream = inputStream; } @@ -77,9 +77,9 @@ public class Java11HttpClientTransport implements Transport { } } - private final Duration timeout; + protected final Duration timeout; - private final HttpClient client; + protected final HttpClient client; public Java11HttpClientTransport() { this(Duration.ofSeconds(10L)); diff --git a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/Context.java b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/Context.java index 404f441..5f3a194 100644 --- a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/Context.java +++ b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/Context.java @@ -33,10 +33,10 @@ import static java.util.Objects.requireNonNull; /** * Class that "disassembles" the query and populates fields and values and exposes them. */ -public final class Context { - private final SearchRequest searchRequest; +public class Context { + protected final SearchRequest searchRequest; - private final Map<Field, String> fields; + protected final Map<Field, String> fields; public Context(SearchRequest searchRequest) { this.searchRequest = requireNonNull(searchRequest); @@ -44,7 +44,7 @@ public final class Context { populateFields(searchRequest.getQuery()); } - private void populateFields(Query query) { + protected void populateFields(Query query) { if (query instanceof BooleanQuery) { populateFields(((BooleanQuery) query).getLeft()); populateFields(((BooleanQuery) query).getRight()); diff --git a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/RecordFactory.java b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/RecordFactory.java index 106eb13..705d52d 100644 --- a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/RecordFactory.java +++ b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/RecordFactory.java @@ -30,9 +30,9 @@ import static java.util.Objects.requireNonNull; /** * Helper class that creates record instances for provided backend. */ -public final class RecordFactory { +public class RecordFactory { - private final RemoteRepositorySearchBackend backend; + protected final RemoteRepositorySearchBackend backend; public RecordFactory(RemoteRepositorySearchBackend backend) { this.backend = requireNonNull(backend); @@ -58,7 +58,7 @@ public final class RecordFactory { return new Record(backend.getBackendId(), backend.getRepositoryId(), null, lastUpdated, result); } - private static void mayPut(Map<Field, Object> result, Field fieldName, Object value) { + protected static void mayPut(Map<Field, Object> result, Field fieldName, Object value) { if (value == null) { return; } diff --git a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/extractor/MavenCentralResponseExtractor.java b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/extractor/MavenCentralResponseExtractor.java index 0e39f39..4fed593 100644 --- a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/extractor/MavenCentralResponseExtractor.java +++ b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/extractor/MavenCentralResponseExtractor.java @@ -35,7 +35,7 @@ public class MavenCentralResponseExtractor extends ResponseExtractorSupport { * attribute contains name in relative form as {@code "name/"} (followed by slash), if name denotes * a directory. The trailing slash is removed by this method, if any. */ - private String nameInHref(Element element) { + protected String nameInHref(Element element) { String name = element.attr("href"); if (name.endsWith("/")) { name = name.substring(0, name.length() - 1); diff --git a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/extractor/Nx2ResponseExtractor.java b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/extractor/Nx2ResponseExtractor.java index 9e5eeb5..752db12 100644 --- a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/extractor/Nx2ResponseExtractor.java +++ b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/extractor/Nx2ResponseExtractor.java @@ -35,7 +35,7 @@ public class Nx2ResponseExtractor extends ResponseExtractorSupport { return !"Parent Directory".equals(name) && super.accept(name); } - private String name(Element element) { + protected String name(Element element) { String name = element.text(); if (name.endsWith("/")) { name = name.substring(0, name.length() - 1); diff --git a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/internal/RemoteRepositorySearchBackendImpl.java b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/internal/RemoteRepositorySearchBackendImpl.java index 2938008..a1bbfe0 100644 --- a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/internal/RemoteRepositorySearchBackendImpl.java +++ b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/internal/RemoteRepositorySearchBackendImpl.java @@ -55,13 +55,13 @@ import static java.util.Objects.requireNonNull; * (HTML parsing) if needed. */ public class RemoteRepositorySearchBackendImpl extends SearchBackendSupport implements RemoteRepositorySearchBackend { - private final String baseUri; + protected final String baseUri; - private final Transport transport; + protected final Transport transport; - private final ResponseExtractor responseExtractor; + protected final ResponseExtractor responseExtractor; - private final Map<String, String> commonHeaders; + protected final Map<String, String> commonHeaders; protected enum State { G, @@ -91,7 +91,7 @@ public class RemoteRepositorySearchBackendImpl extends SearchBackendSupport impl + transport.getClass().getSimpleName()); } - private String discoverVersion() { + protected String discoverVersion() { Properties properties = new Properties(); InputStream inputStream = getClass() .getClassLoader() @@ -214,11 +214,11 @@ public class RemoteRepositorySearchBackendImpl extends SearchBackendSupport impl return new RemoteRepositorySearchResponseImpl(searchRequest, totalHits, page, uri, document); } - private static final DateTimeFormatter RFC7231 = DateTimeFormatter.ofPattern( + protected static final DateTimeFormatter RFC7231 = DateTimeFormatter.ofPattern( "EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH) .withZone(ZoneId.of("GMT")); - private static String readChecksum(InputStream inputStream) throws IOException { + protected static String readChecksum(InputStream inputStream) throws IOException { String checksum = ""; try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8), 512)) { while (true) { diff --git a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/internal/RemoteRepositorySearchResponseImpl.java b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/internal/RemoteRepositorySearchResponseImpl.java index 4970e5f..0835d25 100644 --- a/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/internal/RemoteRepositorySearchResponseImpl.java +++ b/search-backend-remoterepository/src/main/java/org/apache/maven/search/backend/remoterepository/internal/RemoteRepositorySearchResponseImpl.java @@ -31,8 +31,8 @@ import static java.util.Objects.requireNonNull; public class RemoteRepositorySearchResponseImpl extends SearchResponseSupport implements RemoteRepositorySearchResponse { - private final String uri; - private final Document document; + protected final String uri; + protected final Document document; public RemoteRepositorySearchResponseImpl( SearchRequest searchRequest, int totalHits, List<Record> page, String uri, Document document) { diff --git a/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/SmoSearchBackendFactory.java b/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/SmoSearchBackendFactory.java index dcb5679..f10a4e0 100644 --- a/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/SmoSearchBackendFactory.java +++ b/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/SmoSearchBackendFactory.java @@ -26,21 +26,62 @@ import org.apache.maven.search.backend.smo.internal.SmoSearchBackendImpl; * The SMO search backend factory. */ public final class SmoSearchBackendFactory { - public static final String DEFAULT_BACKEND_ID = "central-smo"; + public static final String SMO_BACKEND_ID = "central-smo"; - public static final String DEFAULT_REPOSITORY_ID = "central"; + public static final String SMO_REPOSITORY_ID = "central"; - public static final String DEFAULT_SMO_URI = "https://search.maven.org/solrsearch/select"; + public static final String SMO_SMO_URI = "https://search.maven.org/solrsearch/select"; + + public static final String CSC_BACKEND_ID = "central-csc"; + + public static final String CSC_REPOSITORY_ID = "central"; + + public static final String CSC_SMO_URI = "https://central.sonatype.com/solrsearch/select"; + + /** + * @deprecated Use SMO_ or CSC_ instead. + */ + @Deprecated + public static final String DEFAULT_BACKEND_ID = SMO_BACKEND_ID; + + /** + * @deprecated Use SMO_ or CSC_ instead. + */ + @Deprecated + public static final String DEFAULT_REPOSITORY_ID = SMO_REPOSITORY_ID; + + /** + * @deprecated Use SMO_ or CSC_ instead. + */ + @Deprecated + public static final String DEFAULT_SMO_URI = SMO_SMO_URI; private SmoSearchBackendFactory() {} /** * Creates "default" SMO search backend suitable for most use cases. + * + * @deprecated Use methods {@link #createSmo()} or {@link #createCsc()} instead. */ + @Deprecated public static SmoSearchBackend createDefault() { return create(DEFAULT_BACKEND_ID, DEFAULT_REPOSITORY_ID, DEFAULT_SMO_URI, new Java11HttpClientTransport()); } + /** + * Creates SMO backend. + */ + public static SmoSearchBackend createSmo() { + return create(SMO_BACKEND_ID, SMO_REPOSITORY_ID, SMO_SMO_URI, new Java11HttpClientTransport()); + } + + /** + * Creates CSC backend. + */ + public static SmoSearchBackend createCsc() { + return create(CSC_BACKEND_ID, CSC_REPOSITORY_ID, CSC_SMO_URI, new Java11HttpClientTransport()); + } + /** * Creates SMO search backend using provided parameters. */ diff --git a/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImpl.java b/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImpl.java index 6f8b8b1..8ccb61b 100644 --- a/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImpl.java +++ b/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImpl.java @@ -41,17 +41,17 @@ import org.apache.maven.search.api.SearchRequest; import org.apache.maven.search.api.request.BooleanQuery; import org.apache.maven.search.api.request.Field; import org.apache.maven.search.api.request.FieldQuery; -import org.apache.maven.search.api.request.Paging; import org.apache.maven.search.api.request.Query; import org.apache.maven.search.api.support.SearchBackendSupport; import org.apache.maven.search.api.transport.Transport; import org.apache.maven.search.backend.smo.SmoSearchBackend; +import org.apache.maven.search.backend.smo.SmoSearchBackendFactory; import org.apache.maven.search.backend.smo.SmoSearchResponse; import static java.util.Objects.requireNonNull; public class SmoSearchBackendImpl extends SearchBackendSupport implements SmoSearchBackend { - private static final Map<Field, String> FIELD_TRANSLATION; + protected static final Map<Field, String> FIELD_TRANSLATION; static { FIELD_TRANSLATION = Map.of( @@ -73,11 +73,11 @@ public class SmoSearchBackendImpl extends SearchBackendSupport implements SmoSea "1"); } - private final String smoUri; + protected final String smoUri; - private final Transport transport; + protected final Transport transport; - private final Map<String, String> commonHeaders; + protected final Map<String, String> commonHeaders; /** * Creates a customized instance of SMO backend, like an in-house instances of SMO or different IDs. @@ -95,7 +95,7 @@ public class SmoSearchBackendImpl extends SearchBackendSupport implements SmoSea this.commonHeaders.put("Accept", "application/json"); } - private String discoverVersion() { + protected String discoverVersion() { Properties properties = new Properties(); InputStream inputStream = getClass() .getClassLoader() @@ -125,20 +125,44 @@ public class SmoSearchBackendImpl extends SearchBackendSupport implements SmoSea return new SmoSearchResponseImpl(searchRequest, totalHits, page, searchUri, payload); } - private String toURI(SearchRequest searchRequest) { - Paging paging = searchRequest.getPaging(); + protected String toURI(SearchRequest searchRequest) { HashSet<Field> searchedFields = new HashSet<>(); String smoQuery = toSMOQuery(searchedFields, searchRequest.getQuery()); - smoQuery += "&start=" + paging.getPageSize() * paging.getPageOffset(); - smoQuery += "&rows=" + paging.getPageSize(); - smoQuery += "&wt=json"; + smoQuery += paging(searchRequest, searchedFields); + smoQuery += extra(searchRequest, searchedFields); + return smoUri + "?q=" + smoQuery; + } + + protected String paging(SearchRequest searchRequest, HashSet<Field> searchedFields) { + if (SmoSearchBackendFactory.CSC_BACKEND_ID.equals(backendId)) { + return cscPaging(searchRequest, searchedFields); + } else { + return smoPaging(searchRequest, searchedFields); + } + } + + protected String smoPaging(SearchRequest searchRequest, HashSet<Field> searchedFields) { + return "&start=" + + searchRequest.getPaging().getPageSize() + * searchRequest.getPaging().getPageOffset() + "&rows=" + + searchRequest.getPaging().getPageSize(); + } + + protected String cscPaging(SearchRequest searchRequest, HashSet<Field> searchedFields) { + // this is a bug in CSC: it should work same as SMO but this is life + return "&start=" + searchRequest.getPaging().getPageOffset() + "&rows=" + + searchRequest.getPaging().getPageSize(); + } + + protected String extra(SearchRequest searchRequest, HashSet<Field> searchedFields) { + String extra = "&wt=json"; if (searchedFields.contains(MAVEN.GROUP_ID) && searchedFields.contains(MAVEN.ARTIFACT_ID)) { - smoQuery += "&core=gav"; + extra += "&core=gav"; } - return smoUri + "?q=" + smoQuery; + return extra; } - private String fetch(String serviceUri, Map<String, String> headers) throws IOException { + protected String fetch(String serviceUri, Map<String, String> headers) throws IOException { try (Transport.Response response = transport.get(serviceUri, headers)) { if (response.getCode() == HttpURLConnection.HTTP_OK) { return new String(response.getBody().readAllBytes(), StandardCharsets.UTF_8); @@ -148,7 +172,7 @@ public class SmoSearchBackendImpl extends SearchBackendSupport implements SmoSea } } - private String toSMOQuery(HashSet<Field> searchedFields, Query query) { + protected String toSMOQuery(HashSet<Field> searchedFields, Query query) { if (query instanceof BooleanQuery.And) { BooleanQuery bq = (BooleanQuery) query; return toSMOQuery(searchedFields, bq.getLeft()) + "%20AND%20" + toSMOQuery(searchedFields, bq.getRight()); @@ -165,11 +189,11 @@ public class SmoSearchBackendImpl extends SearchBackendSupport implements SmoSea return encodeQueryParameterValue(query.getValue()); } - private String encodeQueryParameterValue(String parameterValue) { + protected String encodeQueryParameterValue(String parameterValue) { return URLEncoder.encode(parameterValue, StandardCharsets.UTF_8).replace("+", "%20"); } - private int populateFromRaw(JsonObject raw, List<Record> page) { + protected int populateFromRaw(JsonObject raw, List<Record> page) { JsonObject response = raw.getAsJsonObject("response"); Number numFound = response.get("numFound").getAsNumber(); @@ -180,7 +204,7 @@ public class SmoSearchBackendImpl extends SearchBackendSupport implements SmoSea return numFound.intValue(); } - private Record convert(JsonObject doc) { + protected Record convert(JsonObject doc) { HashMap<Field, Object> result = new HashMap<>(); mayPut(result, MAVEN.GROUP_ID, mayGet("g", doc)); @@ -214,15 +238,15 @@ public class SmoSearchBackendImpl extends SearchBackendSupport implements SmoSea result); } - private static final JsonPrimitive EC_SOURCE_JAR = new JsonPrimitive("-sources.jar"); + protected static final JsonPrimitive EC_SOURCE_JAR = new JsonPrimitive("-sources.jar"); - private static final JsonPrimitive EC_JAVADOC_JAR = new JsonPrimitive("-javadoc.jar"); + protected static final JsonPrimitive EC_JAVADOC_JAR = new JsonPrimitive("-javadoc.jar"); - private static String mayGet(String field, JsonObject object) { + protected static String mayGet(String field, JsonObject object) { return object.has(field) ? object.get(field).getAsString() : null; } - private static void mayPut(Map<Field, Object> result, Field fieldName, Object value) { + protected static void mayPut(Map<Field, Object> result, Field fieldName, Object value) { if (value == null) { return; } diff --git a/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/internal/SmoSearchResponseImpl.java b/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/internal/SmoSearchResponseImpl.java index f5cab8d..3e8cb3b 100644 --- a/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/internal/SmoSearchResponseImpl.java +++ b/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/internal/SmoSearchResponseImpl.java @@ -28,9 +28,9 @@ import org.apache.maven.search.backend.smo.SmoSearchResponse; import static java.util.Objects.requireNonNull; public class SmoSearchResponseImpl extends SearchResponseSupport implements SmoSearchResponse { - private final String searchUri; + protected final String searchUri; - private final String rawJsonResponse; + protected final String rawJsonResponse; public SmoSearchResponseImpl( SearchRequest searchRequest, int totalHits, List<Record> page, String searchUri, String rawJsonResponse) { diff --git a/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/SmoSearchTransport.java b/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/CscSearchBackendImplTest.java similarity index 51% rename from search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/SmoSearchTransport.java rename to search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/CscSearchBackendImplTest.java index 685ede7..e4f2070 100644 --- a/search-backend-smo/src/main/java/org/apache/maven/search/backend/smo/SmoSearchTransport.java +++ b/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/CscSearchBackendImplTest.java @@ -16,20 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.search.backend.smo; +package org.apache.maven.search.backend.smo.internal; -import java.io.IOException; -import java.util.Map; +import org.apache.maven.search.backend.smo.SmoSearchBackendFactory; +import org.junit.Ignore; -/** - * A trivial "transport abstraction" to make possible pluggable implementations. - */ -public interface SmoSearchTransport { - /** - * This method should issue a HTTP GET requests using {@code serviceUri} and return body payload as {@link String} - * ONLY if the response was HTTP 200 Ok and there was a payload returned by service. In any other case, it should - * throw, never return {@code null}. The payload is expected to be {@code application/json}, so client may add - * headers to request. Also, the payload is expected to be "relatively small" that may be enforced. - */ - String fetch(String serviceUri, Map<String, String> headers) throws IOException; +@Ignore("This is not a test, is more a showcase") +public class CscSearchBackendImplTest extends SmoSearchBackendTestSupport { + public CscSearchBackendImplTest() { + super(SmoSearchBackendFactory.createCsc()); + } } diff --git a/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImplTest.java b/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImplTest.java index 20649c5..1116cc2 100644 --- a/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImplTest.java +++ b/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImplTest.java @@ -18,146 +18,12 @@ */ package org.apache.maven.search.backend.smo.internal; -import java.io.IOException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.maven.search.api.MAVEN; -import org.apache.maven.search.api.Record; -import org.apache.maven.search.api.SearchRequest; -import org.apache.maven.search.api.request.BooleanQuery; -import org.apache.maven.search.api.request.FieldQuery; -import org.apache.maven.search.api.request.Query; -import org.apache.maven.search.backend.smo.SmoSearchBackend; import org.apache.maven.search.backend.smo.SmoSearchBackendFactory; -import org.apache.maven.search.backend.smo.SmoSearchResponse; import org.junit.Ignore; -import org.junit.Test; @Ignore("This is not a test, is more a showcase") -public class SmoSearchBackendImplTest { - private final SmoSearchBackend backend = SmoSearchBackendFactory.createDefault(); - - private void dumpSingle(AtomicInteger counter, List<Record> page) { - for (Record record : page) { - StringBuilder sb = new StringBuilder(); - sb.append(record.getValue(MAVEN.GROUP_ID)) - .append(":") - .append(record.getValue(MAVEN.ARTIFACT_ID)) - .append(":") - .append(record.getValue(MAVEN.VERSION)); - if (record.hasField(MAVEN.PACKAGING)) { - if (record.hasField(MAVEN.CLASSIFIER)) { - sb.append(":").append(record.getValue(MAVEN.CLASSIFIER)); - } - sb.append(":").append(record.getValue(MAVEN.PACKAGING)); - } - - List<String> remarks = new ArrayList<>(); - if (record.getLastUpdated() != null) { - remarks.add("lastUpdate=" + Instant.ofEpochMilli(record.getLastUpdated())); - } - if (record.hasField(MAVEN.VERSION_COUNT)) { - remarks.add("versionCount=" + record.getValue(MAVEN.VERSION_COUNT)); - } - if (record.hasField(MAVEN.HAS_SOURCE)) { - remarks.add("hasSource=" + record.getValue(MAVEN.HAS_SOURCE)); - } - if (record.hasField(MAVEN.HAS_JAVADOC)) { - remarks.add("hasJavadoc=" + record.getValue(MAVEN.HAS_JAVADOC)); - } - - System.out.print(counter.incrementAndGet() + ". " + sb); - if (!remarks.isEmpty()) { - System.out.print(" " + remarks); - } - System.out.println(); - } - } - - private void dumpPage(SmoSearchResponse searchResponse) throws IOException { - AtomicInteger counter = new AtomicInteger(0); - System.out.println( - "QUERY: " + searchResponse.getSearchRequest().getQuery().toString()); - System.out.println("URL: " + searchResponse.getSearchUri()); - dumpSingle(counter, searchResponse.getPage()); - while (searchResponse.getTotalHits() > searchResponse.getCurrentHits()) { - System.out.println("NEXT PAGE (size " - + searchResponse.getSearchRequest().getPaging().getPageSize() + ")"); - searchResponse = backend.search(searchResponse.getSearchRequest().nextPage()); - dumpSingle(counter, searchResponse.getPage()); - if (counter.get() > 50) { - System.out.println("ABORTED TO NOT SPAM"); - break; // do not spam the SMO service - } - } - System.out.println(); - } - - @Test - public void smoke() throws IOException { - SearchRequest searchRequest = new SearchRequest(Query.query("smoke")); - SmoSearchResponse searchResponse = backend.search(searchRequest); - System.out.println("TOTAL HITS: " + searchResponse.getTotalHits()); - dumpPage(searchResponse); - } - - @Test - public void g() throws IOException { - SearchRequest searchRequest = - new SearchRequest(FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins")); - SmoSearchResponse searchResponse = backend.search(searchRequest); - System.out.println("TOTAL HITS: " + searchResponse.getTotalHits()); - dumpPage(searchResponse); - } - - @Test - public void ga() throws IOException { - SearchRequest searchRequest = new SearchRequest(BooleanQuery.and( - FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"), - FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "maven-clean-plugin"))); - SmoSearchResponse searchResponse = backend.search(searchRequest); - System.out.println("TOTAL HITS: " + searchResponse.getTotalHits()); - dumpPage(searchResponse); - } - - @Test - public void gav() throws IOException { - SearchRequest searchRequest = new SearchRequest(BooleanQuery.and( - FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"), - FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "maven-clean-plugin"), - FieldQuery.fieldQuery(MAVEN.VERSION, "3.1.0"))); - SmoSearchResponse searchResponse = backend.search(searchRequest); - System.out.println("TOTAL HITS: " + searchResponse.getTotalHits()); - dumpPage(searchResponse); - } - - @Test - public void sha1() throws IOException { - SearchRequest searchRequest = - new SearchRequest(FieldQuery.fieldQuery(MAVEN.SHA1, "8ac9e16d933b6fb43bc7f576336b8f4d7eb5ba12")); - SmoSearchResponse searchResponse = backend.search(searchRequest); - System.out.println("TOTAL HITS: " + searchResponse.getTotalHits()); - dumpPage(searchResponse); - } - - @Test - public void cn() throws IOException { - SearchRequest searchRequest = - new SearchRequest(FieldQuery.fieldQuery(MAVEN.CLASS_NAME, "MavenRepositorySystem")); - SmoSearchResponse searchResponse = backend.search(searchRequest); - System.out.println("TOTAL HITS: " + searchResponse.getTotalHits()); - dumpPage(searchResponse); - } - - @Test - public void fqcn() throws IOException { - SearchRequest searchRequest = new SearchRequest( - FieldQuery.fieldQuery(MAVEN.FQ_CLASS_NAME, "org.apache.maven.bridge.MavenRepositorySystem")); - SmoSearchResponse searchResponse = backend.search(searchRequest); - System.out.println("TOTAL HITS: " + searchResponse.getTotalHits()); - dumpPage(searchResponse); +public class SmoSearchBackendImplTest extends SmoSearchBackendTestSupport { + public SmoSearchBackendImplTest() { + super(SmoSearchBackendFactory.createSmo()); } } diff --git a/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImplTest.java b/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendTestSupport.java similarity index 94% copy from search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImplTest.java copy to search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendTestSupport.java index 20649c5..c192b18 100644 --- a/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendImplTest.java +++ b/search-backend-smo/src/test/java/org/apache/maven/search/backend/smo/internal/SmoSearchBackendTestSupport.java @@ -31,16 +31,17 @@ import org.apache.maven.search.api.request.BooleanQuery; import org.apache.maven.search.api.request.FieldQuery; import org.apache.maven.search.api.request.Query; import org.apache.maven.search.backend.smo.SmoSearchBackend; -import org.apache.maven.search.backend.smo.SmoSearchBackendFactory; import org.apache.maven.search.backend.smo.SmoSearchResponse; -import org.junit.Ignore; import org.junit.Test; -@Ignore("This is not a test, is more a showcase") -public class SmoSearchBackendImplTest { - private final SmoSearchBackend backend = SmoSearchBackendFactory.createDefault(); +public abstract class SmoSearchBackendTestSupport { + protected final SmoSearchBackend backend; - private void dumpSingle(AtomicInteger counter, List<Record> page) { + public SmoSearchBackendTestSupport(SmoSearchBackend backend) { + this.backend = backend; + } + + protected void dumpSingle(AtomicInteger counter, List<Record> page) { for (Record record : page) { StringBuilder sb = new StringBuilder(); sb.append(record.getValue(MAVEN.GROUP_ID)) @@ -77,7 +78,7 @@ public class SmoSearchBackendImplTest { } } - private void dumpPage(SmoSearchResponse searchResponse) throws IOException { + protected void dumpPage(SmoSearchResponse searchResponse) throws IOException { AtomicInteger counter = new AtomicInteger(0); System.out.println( "QUERY: " + searchResponse.getSearchRequest().getQuery().toString());