Skip to content
Snippets Groups Projects
Commit 9fc93169 authored by Martin Lowe's avatar Martin Lowe :flag_ca: Committed by Martin Lowe
Browse files

Fix Java version filters #18


Fixed lookup of Java versions in listing versions to convert string
values like 1.7 to a number 7, to take advantage of raw number
comparisons. Fixed issue where version filters weren't properly being
restricted to a single document.

Signed-off-by: Martin Lowe's avatarMartin Lowe <martin.lowe@eclipse-foundation.org>
parent 0e412b30
No related branches found
No related tags found
No related merge requests found
...@@ -18,6 +18,7 @@ import org.bson.codecs.CollectibleCodec; ...@@ -18,6 +18,7 @@ import org.bson.codecs.CollectibleCodec;
import org.bson.codecs.DecoderContext; import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext; import org.bson.codecs.EncoderContext;
import org.eclipsefoundation.marketplace.dto.Install; import org.eclipsefoundation.marketplace.dto.Install;
import org.eclipsefoundation.marketplace.helper.JavaVersionHelper;
import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames; import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames;
import com.mongodb.MongoClient; import com.mongodb.MongoClient;
...@@ -45,7 +46,7 @@ public class InstallCodec implements CollectibleCodec<Install> { ...@@ -45,7 +46,7 @@ public class InstallCodec implements CollectibleCodec<Install> {
Document doc = new Document(); Document doc = new Document();
doc.put(DatabaseFieldNames.DOCID, value.getId()); doc.put(DatabaseFieldNames.DOCID, value.getId());
doc.put(DatabaseFieldNames.INSTALL_JAVA_VERSION, value.getJavaVersion()); doc.put(DatabaseFieldNames.INSTALL_JAVA_VERSION, JavaVersionHelper.convertToDBSafe(value.getJavaVersion()));
doc.put(DatabaseFieldNames.INSTALL_VERSION, value.getVersion()); doc.put(DatabaseFieldNames.INSTALL_VERSION, value.getVersion());
doc.put(DatabaseFieldNames.INSTALL_LISTING_ID, value.getListingId()); doc.put(DatabaseFieldNames.INSTALL_LISTING_ID, value.getListingId());
doc.put(DatabaseFieldNames.INSTALL_DATE, value.getInstallDate()); doc.put(DatabaseFieldNames.INSTALL_DATE, value.getInstallDate());
...@@ -65,7 +66,7 @@ public class InstallCodec implements CollectibleCodec<Install> { ...@@ -65,7 +66,7 @@ public class InstallCodec implements CollectibleCodec<Install> {
Document document = documentCodec.decode(reader, decoderContext); Document document = documentCodec.decode(reader, decoderContext);
Install out = new Install(); Install out = new Install();
out.setId(document.getString(DatabaseFieldNames.DOCID)); out.setId(document.getString(DatabaseFieldNames.DOCID));
out.setJavaVersion(document.getString(DatabaseFieldNames.INSTALL_JAVA_VERSION)); out.setJavaVersion(JavaVersionHelper.convertToDisplayValue(document.getString(DatabaseFieldNames.INSTALL_JAVA_VERSION)));
out.setVersion(document.getString(DatabaseFieldNames.INSTALL_VERSION)); out.setVersion(document.getString(DatabaseFieldNames.INSTALL_VERSION));
out.setListingId(document.getString(DatabaseFieldNames.INSTALL_LISTING_ID)); out.setListingId(document.getString(DatabaseFieldNames.INSTALL_LISTING_ID));
out.setInstallDate(document.getDate(DatabaseFieldNames.INSTALL_DATE)); out.setInstallDate(document.getDate(DatabaseFieldNames.INSTALL_DATE));
......
...@@ -10,6 +10,7 @@ import java.util.stream.Collectors; ...@@ -10,6 +10,7 @@ import java.util.stream.Collectors;
import org.bson.Document; import org.bson.Document;
import org.eclipsefoundation.marketplace.dto.ListingVersion; import org.eclipsefoundation.marketplace.dto.ListingVersion;
import org.eclipsefoundation.marketplace.helper.JavaVersionHelper;
import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames; import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames;
/** /**
...@@ -28,7 +29,7 @@ public class ListingVersionConverter implements Converter<ListingVersion> { ...@@ -28,7 +29,7 @@ public class ListingVersionConverter implements Converter<ListingVersion> {
version.setListingId(src.getString(DatabaseFieldNames.LISTING_ID)); version.setListingId(src.getString(DatabaseFieldNames.LISTING_ID));
version.setEclipseVersions(src.getList("compatible_versions", String.class)); version.setEclipseVersions(src.getList("compatible_versions", String.class));
version.setPlatforms(src.getList("platforms", String.class)); version.setPlatforms(src.getList("platforms", String.class));
version.setMinJavaVersion(src.getString("min_java_version")); version.setMinJavaVersion(JavaVersionHelper.convertToDisplayValue(Integer.toString(src.getInteger("min_java_version"))));
version.setUpdateSiteUrl(src.getString("update_site_url")); version.setUpdateSiteUrl(src.getString("update_site_url"));
version.setVersion(src.getString("version")); version.setVersion(src.getString("version"));
version.setFeatureIds(src.getList(DatabaseFieldNames.FEATURE_IDS, Document.class).stream() version.setFeatureIds(src.getList(DatabaseFieldNames.FEATURE_IDS, Document.class).stream()
...@@ -43,7 +44,7 @@ public class ListingVersionConverter implements Converter<ListingVersion> { ...@@ -43,7 +44,7 @@ public class ListingVersionConverter implements Converter<ListingVersion> {
doc.put(DatabaseFieldNames.LISTING_ID, src.getListingId()); doc.put(DatabaseFieldNames.LISTING_ID, src.getListingId());
doc.put("compatible_versions", src.getEclipseVersions()); doc.put("compatible_versions", src.getEclipseVersions());
doc.put("platforms", src.getPlatforms()); doc.put("platforms", src.getPlatforms());
doc.put("min_java_version", src.getMinJavaVersion()); doc.put("min_java_version", Integer.valueOf(JavaVersionHelper.convertToDBSafe(src.getMinJavaVersion())));
doc.put("update_site_url", src.getUpdateSiteUrl()); doc.put("update_site_url", src.getUpdateSiteUrl());
doc.put("version", src.getVersion()); doc.put("version", src.getVersion());
doc.put(DatabaseFieldNames.FEATURE_IDS, doc.put(DatabaseFieldNames.FEATURE_IDS,
......
...@@ -7,13 +7,12 @@ ...@@ -7,13 +7,12 @@
package org.eclipsefoundation.marketplace.dto.filter; package org.eclipsefoundation.marketplace.dto.filter;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.bson.conversions.Bson; import org.bson.conversions.Bson;
import org.eclipsefoundation.marketplace.model.RequestWrapper; import org.eclipsefoundation.marketplace.model.RequestWrapper;
import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Filters;
/** /**
* Filter interface for usage when querying data. * Filter interface for usage when querying data.
...@@ -35,7 +34,7 @@ public interface DtoFilter<T> { ...@@ -35,7 +34,7 @@ public interface DtoFilter<T> {
/** /**
* Retrieve aggregate filter operations for the current arguments. * Retrieve aggregate filter operations for the current arguments.
* *
* @param wrap wrapper for the current request * @param wrap wrapper for the current request
* @return list of aggregates for the current request, or empty if there are no * @return list of aggregates for the current request, or empty if there are no
* applicable aggregates. * applicable aggregates.
*/ */
...@@ -58,18 +57,12 @@ public interface DtoFilter<T> { ...@@ -58,18 +57,12 @@ public interface DtoFilter<T> {
* @return a list of aggregate pipeline operations representing the filters for * @return a list of aggregate pipeline operations representing the filters for
* the current request. * the current request.
*/ */
default List<Bson> wrapFiltersToAggregate(RequestWrapper wrap, String nestedPath) { default Bson wrapFiltersToAggregate(RequestWrapper wrap, String nestedPath) {
return getFilters(wrap, nestedPath).stream().map(Aggregates::match).collect(Collectors.toList()); List<Bson> filters = getFilters(wrap, nestedPath);
} if (!filters.isEmpty()) {
return Aggregates.match(Filters.elemMatch(nestedPath, Filters.and(filters)));
/** }
* return null;
* @param root
* @param fieldName
* @return
*/
default String getPath(String root, String fieldName) {
return StringUtils.isBlank(root) ? fieldName : root + '.' + fieldName;
} }
/** /**
......
...@@ -81,7 +81,10 @@ public class ListingFilter implements DtoFilter<Listing> { ...@@ -81,7 +81,10 @@ public class ListingFilter implements DtoFilter<Listing> {
// adds a $lookup aggregate, joining categories on categoryIDS as "categories" // adds a $lookup aggregate, joining categories on categoryIDS as "categories"
aggs.add(Aggregates.lookup(DtoTableNames.LISTING_VERSION.getTableName(), DatabaseFieldNames.DOCID, DatabaseFieldNames.LISTING_ID, aggs.add(Aggregates.lookup(DtoTableNames.LISTING_VERSION.getTableName(), DatabaseFieldNames.DOCID, DatabaseFieldNames.LISTING_ID,
DatabaseFieldNames.LISTING_VERSIONS)); DatabaseFieldNames.LISTING_VERSIONS));
aggs.addAll(listingVersionFilter.wrapFiltersToAggregate(wrap, DatabaseFieldNames.LISTING_VERSIONS)); Bson filters = listingVersionFilter.wrapFiltersToAggregate(wrap, DatabaseFieldNames.LISTING_VERSIONS);
if (filters != null) {
aggs.add(filters);
}
aggs.add(Aggregates.lookup(DtoTableNames.CATEGORY.getTableName(), DatabaseFieldNames.CATEGORY_IDS, aggs.add(Aggregates.lookup(DtoTableNames.CATEGORY.getTableName(), DatabaseFieldNames.CATEGORY_IDS,
DatabaseFieldNames.DOCID, DatabaseFieldNames.LISTING_CATEGORIES)); DatabaseFieldNames.DOCID, DatabaseFieldNames.LISTING_CATEGORIES));
List<String> marketIds = wrap.getParams(UrlParameterNames.MARKET_IDS); List<String> marketIds = wrap.getParams(UrlParameterNames.MARKET_IDS);
......
...@@ -13,6 +13,7 @@ import java.util.Optional; ...@@ -13,6 +13,7 @@ import java.util.Optional;
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ApplicationScoped;
import org.apache.commons.lang3.StringUtils;
import org.bson.conversions.Bson; import org.bson.conversions.Bson;
import org.eclipsefoundation.marketplace.dto.ListingVersion; import org.eclipsefoundation.marketplace.dto.ListingVersion;
import org.eclipsefoundation.marketplace.model.RequestWrapper; import org.eclipsefoundation.marketplace.model.RequestWrapper;
...@@ -45,21 +46,19 @@ public class ListingVersionFilter implements DtoFilter<ListingVersion> { ...@@ -45,21 +46,19 @@ public class ListingVersionFilter implements DtoFilter<ListingVersion> {
// solution version - OS filter // solution version - OS filter
Optional<String> os = wrap.getFirstParam(UrlParameterNames.OS); Optional<String> os = wrap.getFirstParam(UrlParameterNames.OS);
if (os.isPresent()) { if (os.isPresent()) {
filters.add(Filters.eq(getPath(root, "platforms"), os.get())); filters.add(Filters.eq("platforms", os.get()));
} }
// solution version - eclipse version // solution version - eclipse version
Optional<String> eclipseVersion = wrap.getFirstParam(UrlParameterNames.ECLIPSE_VERSION); Optional<String> eclipseVersion = wrap.getFirstParam(UrlParameterNames.ECLIPSE_VERSION);
if (eclipseVersion.isPresent()) { if (eclipseVersion.isPresent()) {
filters.add(Filters.eq(getPath(root, "compatible_versions"), eclipseVersion.get())); filters.add(Filters.eq("compatible_versions", eclipseVersion.get()));
} }
// TODO this sorts by naturally by character rather than by actual number (e.g.
// 1.9 is technically greater than 1.10)
// solution version - Java version // solution version - Java version
Optional<String> javaVersion = wrap.getFirstParam(UrlParameterNames.JAVA_VERSION); Optional<String> javaVersion = wrap.getFirstParam(UrlParameterNames.JAVA_VERSION);
if (javaVersion.isPresent()) { if (javaVersion.isPresent() && StringUtils.isNumeric(javaVersion.get())) {
filters.add(Filters.gte(getPath(root, "min_java_version"), javaVersion.get())); filters.add(Filters.gte("min_java_version", Integer.valueOf(javaVersion.get())));
} }
return filters; return filters;
} }
......
/* Copyright (c) 2019 Eclipse Foundation and others.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License 2.0
* which is available at http://www.eclipse.org/legal/epl-v20.html,
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipsefoundation.marketplace.helper;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
/**
* Used to handle the conversion of Java versions to and from storage mediums.
*
* @author Martin Lowe
*
*/
public class JavaVersionHelper {
// checks retrieves both possible major versions in Java-version strings
private static final Pattern MAJOR_VERSION_CHECK = Pattern.compile("^(\\d+)\\.(\\d+)(?:\\.[\\d_]+){0,}");
/**
* Converts value to strip out parts of Java version string that cause issues
* with natural number sorting in databases.
*
* @param val the java version string to convert (e.g. 1.7, 10.0.1)
* @return modified and more sortable version string, or null if it doesn't
* match Java version strings
*/
public static final String convertToDBSafe(String val) {
String out = val;
if (StringUtils.isBlank(out)) {
return null;
}
// strip out the major Java version as it isn't useful.
Matcher m = MAJOR_VERSION_CHECK.matcher(out);
if (m.matches()) {
String majorVersion = m.group(1);
// if we have a major version of 1, this indicates old school java and we should
// use the second group as the product version
if ("1".equals(majorVersion)) {
out = m.group(2);
} else {
out = majorVersion;
}
return out;
}
return null;
}
/**
* Converts the sortable DB value for the Java version to something more in line
* with what is expected by the user.
*
* @param val the sortable stored version string
* @return display value of the sortable Java version
*/
public static final String convertToDisplayValue(String val) {
String out = val;
if (StringUtils.isBlank(out) || !StringUtils.isNumeric(val)) {
return null;
}
// check that the is 5,6,7,8 before adding a "1." in front
if (val.equals("5") || val.equals("6") || val.equals("7") || val.equals("8")) {
// add major version of 1 to string
out = "1." + val;
}
return out;
}
private JavaVersionHelper() {
}
}
/* Copyright (c) 2019 Eclipse Foundation and others.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License 2.0
* which is available at http://www.eclipse.org/legal/epl-v20.html,
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipsefoundation.marketplace.helper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
/**
* Test class for {@linkplain JavaVersionHelper}
*
* @author Martin Lowe
*/
@QuarkusTest
public class JavaVersionHelperTest {
@Test
public void testConvertToDBSafe() {
Assertions.assertEquals("7", JavaVersionHelper.convertToDBSafe("1.7"));
Assertions.assertEquals("7", JavaVersionHelper.convertToDBSafe("1.7.0_4"));
Assertions.assertEquals("8", JavaVersionHelper.convertToDBSafe("1.8.45"));
Assertions.assertEquals("8", JavaVersionHelper.convertToDBSafe("8.1.45"));
Assertions.assertEquals("11", JavaVersionHelper.convertToDBSafe("11.1.2"));
Assertions.assertEquals(null, JavaVersionHelper.convertToDBSafe("';DROP TABLES;"));
Assertions.assertEquals(null, JavaVersionHelper.convertToDBSafe(" "));
Assertions.assertEquals(null, JavaVersionHelper.convertToDBSafe(null));
}
@Test
public void testConvertToDisplayValue() {
Assertions.assertEquals("1.7", JavaVersionHelper.convertToDisplayValue("7"));
Assertions.assertEquals("1.8", JavaVersionHelper.convertToDisplayValue("8"));
Assertions.assertEquals("9", JavaVersionHelper.convertToDisplayValue("9"));
Assertions.assertEquals("11", JavaVersionHelper.convertToDisplayValue("11"));
Assertions.assertEquals(null, JavaVersionHelper.convertToDisplayValue("11.1"));
Assertions.assertEquals(null, JavaVersionHelper.convertToDisplayValue("';DROP TABLES;"));
Assertions.assertEquals(null, JavaVersionHelper.convertToDisplayValue(" "));
Assertions.assertEquals(null, JavaVersionHelper.convertToDisplayValue(null));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment