Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support default sort parameters for WFS 1.1.0 sources. #6741

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public class Wfs11Constants extends WfsConstants {

public static final QName MULTI_POLYGON = new QName(GML_3_1_1_NAMESPACE, "MultiPolygon");

/**
* This is a list of sort-by attribute names that were removed from the query because they are
* known to be unsupported by the source. In practice, this value will be suffixed with
* ".SOURCE_ID".
*/
public static final String UNSUPPORTED_SORT_BY_REMOVED = "unsupported-sort-by-removed";

public static List<QName> wktOperandsAsList() {
return Arrays.asList(
LINEAR_RING,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.68</minimum>
<minimum>0.69</minimum>
</limit>
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>COMPLEXITY</counter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import ddf.catalog.data.impl.ContentTypeImpl;
import ddf.catalog.data.impl.ResultImpl;
import ddf.catalog.filter.FilterAdapter;
import ddf.catalog.filter.impl.SortByImpl;
import ddf.catalog.operation.Query;
import ddf.catalog.operation.QueryRequest;
import ddf.catalog.operation.ResourceResponse;
Expand Down Expand Up @@ -86,6 +87,7 @@
import net.opengis.wfs.v_1_1_0.WFSCapabilitiesType;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.apache.ws.commons.schema.XmlSchema;
import org.codice.ddf.configuration.DictionaryMap;
Expand Down Expand Up @@ -195,6 +197,12 @@ public class WfsSource extends AbstractWfsSource {

private final ClientBuilderFactory clientBuilderFactory;

// may be null
private String defaultSortName;

// may be null
private SortOrder defaultSortOrder;

private String wfsUrl;

private String wfsVersion;
Expand Down Expand Up @@ -365,6 +373,14 @@ public void refresh(Map<String, Object> configuration) {
}
}

public void setDefaultSortName(String name) {
this.defaultSortName = name;
}

public void setDefaultSortOrder(String order) {
this.defaultSortOrder = SortOrder.valueOf(order);
}

public void setAllowRedirects(Boolean allowRedirects) {
this.allowRedirects = allowRedirects;
}
Expand Down Expand Up @@ -724,7 +740,8 @@ public SourceResponse query(QueryRequest request) throws UnsupportedQueryExcepti
}

final ExtendedGetFeatureType getHits = buildGetFeatureRequestHits(modifiedQuery);
final ExtendedGetFeatureType getResults = buildGetFeatureRequestResults(modifiedQuery);
final Pair<ExtendedGetFeatureType, Map<String, Serializable>> getResults =
buildGetFeatureRequestResults(modifiedQuery);

try {
LOGGER.debug("WFS Source {}: Getting hits.", getId());
Expand All @@ -745,7 +762,7 @@ public SourceResponse query(QueryRequest request) throws UnsupportedQueryExcepti
LOGGER.debug("The query has {} hits.", totalHits);

LOGGER.debug("WFS Source {}: Sending query ...", getId());
final WfsFeatureCollection featureCollection = wfs.getFeature(getResults);
final WfsFeatureCollection featureCollection = wfs.getFeature(getResults.getLeft());

if (featureCollection == null) {
throw new UnsupportedQueryException("Invalid results returned from server");
Expand Down Expand Up @@ -789,7 +806,8 @@ public SourceResponse query(QueryRequest request) throws UnsupportedQueryExcepti
}
}

return new SourceResponseImpl(request, null, results, totalHits, sourceProcessingDetails);
return new SourceResponseImpl(
request, getResults.getRight(), results, totalHits, sourceProcessingDetails);
} catch (WfsException wfse) {
LOGGER.debug(WFS_ERROR_MESSAGE, wfse);
throw new UnsupportedQueryException("Error received from WFS Server", wfse);
Expand All @@ -813,20 +831,21 @@ private void addTransformedResult(Metacard mc, List<Result> results) {

private ExtendedGetFeatureType buildGetFeatureRequestHits(final Query query)
throws UnsupportedQueryException {
return buildGetFeatureRequest(query, ResultTypeType.HITS, null);
return buildGetFeatureRequest(query, ResultTypeType.HITS, null).getLeft();
}

private ExtendedGetFeatureType buildGetFeatureRequestResults(final Query query)
throws UnsupportedQueryException {
private Pair<ExtendedGetFeatureType, Map<String, Serializable>> buildGetFeatureRequestResults(
final Query query) throws UnsupportedQueryException {
return buildGetFeatureRequest(
query, ResultTypeType.RESULTS, BigInteger.valueOf(query.getPageSize()));
}

private ExtendedGetFeatureType buildGetFeatureRequest(
private Pair<ExtendedGetFeatureType, Map<String, Serializable>> buildGetFeatureRequest(
Query query, ResultTypeType resultType, BigInteger maxFeatures)
throws UnsupportedQueryException {
List<ContentType> contentTypes = getContentTypesFromQuery(query);
List<QueryType> queries = new ArrayList<>();
Map<String, Serializable> properties = null;

for (Entry<QName, WfsFilterDelegate> filterDelegateEntry : featureTypeFilters.entrySet()) {
if (contentTypes.isEmpty()
Expand All @@ -845,22 +864,7 @@ private ExtendedGetFeatureType buildGetFeatureRequest(
&& query.getSortBy() != null
&& query.getSortBy().getPropertyName() != null
&& query.getSortBy().getPropertyName().getPropertyName() != null) {
SortByType sortByType = buildSortBy(filterDelegateEntry.getKey(), query.getSortBy());
if (sortByType != null
&& sortByType.getSortProperty() != null
&& sortByType.getSortProperty().size() > 0) {
LOGGER.debug(
"Sorting using sort property [{}] and sort order [{}].",
sortByType.getSortProperty().get(0).getPropertyName(),
sortByType.getSortProperty().get(0).getSortOrder());
wfsQuery.setSortBy(sortByType);
} else {
throw new UnsupportedQueryException(
"Source "
+ this.getId()
+ " does not support specified sort property "
+ query.getSortBy().getPropertyName().getPropertyName());
}
properties = setSortBy(query.getSortBy(), filterDelegateEntry.getKey(), wfsQuery);
} else {
LOGGER.debug("Sorting is disabled or sort not specified.");
}
Expand All @@ -883,13 +887,70 @@ private ExtendedGetFeatureType buildGetFeatureRequest(
getFeatureType.setStartIndex(BigInteger.valueOf(query.getStartIndex() - 1));
}
logMessage(getFeatureType);
return getFeatureType;
return Pair.of(getFeatureType, properties);
} else {
throw new UnsupportedQueryException(
"Unable to build query. No filters could be created from query criteria.");
}
}

/**
* If the query-supplied sort parameters are valid, then use them. If they are not valid, then
* fallback to the default sort parameters. If the default sort parameters are unset, then return
* without error. If the default sort parameters are valid, then use them. If the default sort
* parameters are invalid, then throw an exception.
*
* <p>Returns a properties map that includes information indicating if the sort parameters were
* changed to the default.
*/
private Map<String, Serializable> setSortBy(SortBy sortBy, QName key, QueryType wfsQuery)
throws UnsupportedQueryException {
SortByType sortByType = buildSortBy(key, sortBy);
if (isSortByValid(sortByType)) {
logSortBy(sortByType);
wfsQuery.setSortBy(sortByType);
return null;
}

Map<String, Serializable> properties = new HashMap<>();
properties.put(
Wfs11Constants.UNSUPPORTED_SORT_BY_REMOVED + "." + getId(),
sortBy.getPropertyName().getPropertyName());

if (defaultSortName == null || defaultSortOrder == null) {
LOGGER.debug(
"Skipping sorting because the query-supplied sort property [{}] is not supported and the default sort property and default sort order are not set.",
sortBy.getPropertyName().getPropertyName());
return properties;
}

sortByType = buildSortBy(key, new SortByImpl(defaultSortName, defaultSortOrder));
if (isSortByValid(sortByType)) {
logSortBy(sortByType);
wfsQuery.setSortBy(sortByType);
return properties;
} else {
throw new UnsupportedQueryException(
"Source "
+ this.getId()
+ " does not support the default sort property "
+ defaultSortName);
}
}

private void logSortBy(SortByType sortByType) {
LOGGER.debug(
"Sorting using sort property [{}] and sort order [{}].",
sortByType.getSortProperty().get(0).getPropertyName(),
sortByType.getSortProperty().get(0).getSortOrder());
}

private boolean isSortByValid(SortByType sortByType) {
return sortByType != null
&& sortByType.getSortProperty() != null
&& sortByType.getSortProperty().size() > 0;
}

private SortByType buildSortBy(QName featureType, SortBy incomingSortBy) {
net.opengis.filter.v_1_1_0.ObjectFactory filterObjectFactory =
new net.opengis.filter.v_1_1_0.ObjectFactory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@
<AD description="Forces the source to support all geometry operands."
name="Force All Geometry Operands" id="forceAllGeometryOperands" required="false"
type="Boolean" default="false"/>
<AD description="Set the default sort attribute name (optional). If the default sort attribute is set, then the default sort order must be set."
name="Default Sort Attribute" id="defaultSortName" required="false"
type="String"/>
<AD description="Set the default sort order (optional). If the default sort order is set, then the default sort attribute must be set. Allowed values: ASCENDING, DESCENDING"
name="Default Sort Order" id="defaultSortOrder" required="false"
type="String"/>
</OCD>

<Designate pid="Wfs_v110_Federated_Source" factoryPid="Wfs_v110_Federated_Source">
Expand Down
Loading