Skip to content

Commit

Permalink
OSEO admin REST API, products read only portion
Browse files Browse the repository at this point in the history
  • Loading branch information
aaime committed Jun 21, 2017
1 parent cbb5bb1 commit 532cea5
Show file tree
Hide file tree
Showing 12 changed files with 623 additions and 89 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,19 +14,16 @@
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;


import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.Predicates; import org.geoserver.catalog.Predicates;
import org.geoserver.config.GeoServer; import org.geoserver.config.GeoServer;
import org.geoserver.opensearch.eo.store.OpenSearchAccess; import org.geoserver.opensearch.eo.store.OpenSearchAccess;
import org.geoserver.opensearch.eo.store.OpenSearchAccess.ProductClass; import org.geoserver.opensearch.eo.store.OpenSearchAccess.ProductClass;
import org.geoserver.platform.OWS20Exception; import org.geoserver.platform.OWS20Exception;
import org.geoserver.platform.OWS20Exception.OWSExceptionCode; import org.geoserver.platform.OWS20Exception.OWSExceptionCode;
import org.geotools.data.DataAccess;
import org.geotools.data.DataUtilities; import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureSource; import org.geotools.data.FeatureSource;
import org.geotools.data.Parameter; import org.geotools.data.Parameter;
import org.geotools.data.Query; import org.geotools.data.Query;
import org.geotools.data.memory.MemoryFeatureCollection;
import org.geotools.factory.CommonFactoryFinder; import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureCollection;
import org.geotools.feature.NameImpl; import org.geotools.feature.NameImpl;
Expand Down Expand Up @@ -300,7 +297,12 @@ public QuicklookResults quicklook(QuicklookRequest request) throws IOException {
return new QuicklookResults(request, payload, guessImageMimeType(payload)); return new QuicklookResults(request, payload, guessImageMimeType(payload));
} }


private String guessImageMimeType(byte[] payload) { /**
* Used to guess the mime type of an encoded image until we start storing the mime in the db
* @param payload
* @return
*/
public static String guessImageMimeType(byte[] payload) {
// guesses jpeg and png by the magic number // guesses jpeg and png by the magic number
if (payload.length >= 4 && // if (payload.length >= 4 && //
(payload[0] == (byte) 0xFF) && // (payload[0] == (byte) 0xFF) && //
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -390,7 +390,6 @@ public void testSpecificProduct() throws Exception {


// check the HTML // check the HTML
String summary = getXPath().compile("/at:feed/at:entry[1]/at:summary").evaluate(dom); String summary = getXPath().compile("/at:feed/at:entry[1]/at:summary").evaluate(dom);
System.out.println(summary);
// parse html using JSoup (DOM not usable, HTML is not valid/well formed XML in general // parse html using JSoup (DOM not usable, HTML is not valid/well formed XML in general
org.jsoup.nodes.Document sd = Jsoup.parse(summary); org.jsoup.nodes.Document sd = Jsoup.parse(summary);
String isoHRef = sd.select("a[title=O&M format]").attr("href"); String isoHRef = sd.select("a[title=O&M format]").attr("href");
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ VALUES(353, '<?xml version="1.0" encoding="UTF-8"?>
</om:result> </om:result>
<eop:metaDataProperty> <eop:metaDataProperty>
<eop:EarthObservationMetaData> <eop:EarthObservationMetaData>
<eop:identifier></eop:identifier> <eop:identifier>S2A_OPER_MSI_L1C_TL_SGS__20160117T141030_A002979_T32TPL_N02.01</eop:identifier>
<eop:creationDate>2016-01-18T21:05:18.000706Z</eop:creationDate> <eop:creationDate>2016-01-18T21:05:18.000706Z</eop:creationDate>
<eop:modificationDate></eop:modificationDate> <eop:modificationDate></eop:modificationDate>
<eop:parentIdentifier>S2_MSI_L1C</eop:parentIdentifier> <eop:parentIdentifier>S2_MSI_L1C</eop:parentIdentifier>
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@
package org.geoserver.opensearch.rest; package org.geoserver.opensearch.rest;


import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;


import org.geoserver.opensearch.eo.OpenSearchAccessProvider; import org.geoserver.opensearch.eo.OpenSearchAccessProvider;
import org.geoserver.opensearch.eo.response.LinkFeatureComparator;
import org.geoserver.opensearch.eo.store.OpenSearchAccess; import org.geoserver.opensearch.eo.store.OpenSearchAccess;
import org.geoserver.opensearch.eo.store.OpenSearchAccess.ProductClass; import org.geoserver.opensearch.eo.store.OpenSearchAccess.ProductClass;
import org.geoserver.rest.ResourceNotFoundException;
import org.geoserver.rest.RestBaseController; import org.geoserver.rest.RestBaseController;
import org.geoserver.rest.RestException; import org.geoserver.rest.RestException;
import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator; import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.factory.CommonFactoryFinder; import org.geotools.factory.CommonFactoryFinder;
Expand Down Expand Up @@ -68,6 +76,44 @@ protected void validateMax(Integer value, int max, String name) {
} }
} }


protected void setupQueryPaging(Query query, Integer offset, Integer limit) {
if (offset != null) {
validateMin(offset, 0, "offset");
query.setStartIndex(offset);
}
final int maximumRecordsPerPage = accessProvider.getService().getMaximumRecordsPerPage();
if (limit != null) {
validateMin(limit, 0, "limit");
validateMax(limit, maximumRecordsPerPage, "limit");
query.setMaxFeatures(limit);
} else {
query.setMaxFeatures(maximumRecordsPerPage);
}
}

protected FeatureCollection<FeatureType, Feature> queryCollections(Query query)
throws IOException {
OpenSearchAccess access = accessProvider.getOpenSearchAccess();
FeatureSource<FeatureType, Feature> fs = access.getCollectionSource();
FeatureCollection<FeatureType, Feature> fc = fs.getFeatures(query);
return fc;
}

protected Feature queryCollection(String collectionName, Consumer<Query> queryDecorator)
throws IOException {
Query query = new Query();
query.setFilter(FF.equal(FF.property("name"), FF.literal(collectionName), true));
queryDecorator.accept(query);
FeatureCollection<FeatureType, Feature> fc = queryCollections(query);
Feature feature = DataUtilities.first(fc);
if (feature == null) {
throw new ResourceNotFoundException(
"Could not find a collection named '" + collectionName + "'");
}

return feature;
}

protected SimpleFeatureType mapFeatureTypeToSimple(FeatureType schema, protected SimpleFeatureType mapFeatureTypeToSimple(FeatureType schema,
Consumer<SimpleFeatureTypeBuilder> extraAttributeBuilder) { Consumer<SimpleFeatureTypeBuilder> extraAttributeBuilder) {
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
Expand Down Expand Up @@ -108,6 +154,25 @@ protected SimpleFeatureType mapFeatureTypeToSimple(FeatureType schema,
SimpleFeatureType targetSchema = tb.buildFeatureType(); SimpleFeatureType targetSchema = tb.buildFeatureType();
return targetSchema; return targetSchema;
} }

protected OgcLinks buildOgcLinksFromFeature(Feature feature) {
// map to a list of beans
List<OgcLink> links = Collections.emptyList();
Collection<Property> linkProperties = feature
.getProperties(OpenSearchAccess.OGC_LINKS_PROPERTY_NAME);
if (linkProperties != null) {
links = linkProperties.stream().map(p -> (SimpleFeature) p)
.sorted(LinkFeatureComparator.INSTANCE).map(sf -> {
String offering = (String) sf.getAttribute("offering");
String method = (String) sf.getAttribute("method");
String code = (String) sf.getAttribute("code");
String type = (String) sf.getAttribute("type");
String href = (String) sf.getAttribute("href");
return new OgcLink(offering, method, code, type, href);
}).collect(Collectors.toList());
}
return new OgcLinks(links);
}


protected SimpleFeature mapFeatureToSimple(Feature f, SimpleFeatureType targetSchema, protected SimpleFeature mapFeatureToSimple(Feature f, SimpleFeatureType targetSchema,
Consumer<SimpleFeatureBuilder> extraValueBuilder) { Consumer<SimpleFeatureBuilder> extraValueBuilder) {
Expand All @@ -121,7 +186,9 @@ protected SimpleFeature mapFeatureToSimple(Feature f, SimpleFeatureType targetSc
Object value = p.getValue(); Object value = p.getValue();
if (value != null) { if (value != null) {
fb.set(ad.getLocalName(), value); fb.set(ad.getLocalName(), value);
if ("eo:identifier".equals(ad.getLocalName()) && value instanceof String) { if (("eo:identifier".equals(ad.getLocalName())
|| "eop:identifier".equals(ad.getLocalName()))
&& value instanceof String) {
identifier = (String) value; identifier = (String) value;
} }
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;


import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
Expand All @@ -23,7 +22,6 @@
import org.geoserver.ows.util.ResponseUtils; import org.geoserver.ows.util.ResponseUtils;
import org.geoserver.rest.ResourceNotFoundException; import org.geoserver.rest.ResourceNotFoundException;
import org.geoserver.rest.RestBaseController; import org.geoserver.rest.RestBaseController;
import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureSource; import org.geotools.data.FeatureSource;
import org.geotools.data.Query; import org.geotools.data.Query;
import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureCollection;
Expand Down Expand Up @@ -65,18 +63,7 @@ public CollectionReferences getCollections(HttpServletRequest request,
@RequestParam(name = "limit", required = false) Integer limit) throws IOException { @RequestParam(name = "limit", required = false) Integer limit) throws IOException {
// query the collections for their names // query the collections for their names
Query query = new Query(); Query query = new Query();
if (offset != null) { setupQueryPaging(query, offset, limit);
validateMin(offset, 0, "offset");
query.setStartIndex(offset);
}
final int maximumRecordsPerPage = accessProvider.getService().getMaximumRecordsPerPage();
if (limit != null) {
validateMin(limit, 0, "limit");
validateMax(limit, maximumRecordsPerPage, "limit");
query.setMaxFeatures(limit);
} else {
query.setMaxFeatures(maximumRecordsPerPage);
}
query.setSortBy(new SortBy[] { FF.sort("name", SortOrder.ASCENDING) }); query.setSortBy(new SortBy[] { FF.sort("name", SortOrder.ASCENDING) });
query.setPropertyNames(new String[] { "name" }); query.setPropertyNames(new String[] { "name" });
OpenSearchAccess access = accessProvider.getOpenSearchAccess(); OpenSearchAccess access = accessProvider.getOpenSearchAccess();
Expand Down Expand Up @@ -144,22 +131,8 @@ public OgcLinks getCollectionOgcLinks(HttpServletRequest request,
.singletonList(FF.property(OpenSearchAccess.OGC_LINKS_PROPERTY_NAME))); .singletonList(FF.property(OpenSearchAccess.OGC_LINKS_PROPERTY_NAME)));
}); });


// map to a list of beans OgcLinks links = buildOgcLinksFromFeature(feature);
List<OgcLink> links = Collections.emptyList(); return links;
Collection<Property> linkProperties = feature
.getProperties(OpenSearchAccess.OGC_LINKS_PROPERTY_NAME);
if (linkProperties != null) {
links = linkProperties.stream().map(p -> (SimpleFeature) p)
.sorted(LinkFeatureComparator.INSTANCE).map(sf -> {
String offering = (String) sf.getAttribute("offering");
String method = (String) sf.getAttribute("method");
String code = (String) sf.getAttribute("code");
String type = (String) sf.getAttribute("type");
String href = (String) sf.getAttribute("href");
return new OgcLink(offering, method, code, type, href);
}).collect(Collectors.toList());
}
return new OgcLinks(links);
} }


@GetMapping(path = "{collection}/metadata", produces = { MediaType.TEXT_XML_VALUE }) @GetMapping(path = "{collection}/metadata", produces = { MediaType.TEXT_XML_VALUE })
Expand Down Expand Up @@ -204,27 +177,5 @@ public void getCollectionDescription(@PathVariable(name = "collection", required
} }
} }


protected FeatureCollection<FeatureType, Feature> queryCollections(Query query)
throws IOException {
OpenSearchAccess access = accessProvider.getOpenSearchAccess();
FeatureSource<FeatureType, Feature> fs = access.getCollectionSource();
FeatureCollection<FeatureType, Feature> fc = fs.getFeatures(query);
return fc;
}

protected Feature queryCollection(String collectionName, Consumer<Query> queryDecorator)
throws IOException {
Query query = new Query();
query.setFilter(FF.equal(FF.property("name"), FF.literal(collectionName), true));
queryDecorator.accept(query);
FeatureCollection<FeatureType, Feature> fc = queryCollections(query);
Feature feature = DataUtilities.first(fc);
if (feature == null) {
throw new ResourceNotFoundException(
"Could not find a collection named '" + collectionName + "'");
}

return feature;
}


} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -21,24 +21,30 @@


@Component @Component
public class OseoJSONConverter extends BaseMessageConverter<Object> { public class OseoJSONConverter extends BaseMessageConverter<Object> {


private XStream xs;

public OseoJSONConverter() { public OseoJSONConverter() {
super(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8); super(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8);

xs = new SecureXStream(new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE | JsonWriter.STRICT_MODE);
}
});

} }


@Override @Override
protected boolean supports(Class clazz) { protected boolean supports(Class clazz) {
return CollectionReferences.class.isAssignableFrom(clazz) || OgcLinks.class.isAssignableFrom(clazz); return CollectionReferences.class.isAssignableFrom(clazz)
|| ProductReferences.class.isAssignableFrom(clazz)
|| OgcLinks.class.isAssignableFrom(clazz);
} }

@Override @Override
protected void writeInternal(Object t, HttpOutputMessage outputMessage) protected void writeInternal(Object t, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException { throws IOException, HttpMessageNotWritableException {
XStream xs = new SecureXStream(new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE | JsonWriter.STRICT_MODE );
}
});
xs.toXML(t, outputMessage.getBody()); xs.toXML(t, outputMessage.getBody());
} }


Expand Down
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,39 @@
/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.opensearch.rest;

/**
* Bean used for JSON serialization
*
* @author Andrea Aime - GeoSolutions
*/
class ProductReference {

String id;

String href;

String rss;

public ProductReference(String id, String href, String search) {
super();
this.id = id ;
this.href = href;
this.rss = search;
}

public String getId() {
return id;
}

public String getHref() {
return href;
}

public String getRss() {
return rss;
}

}
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,22 @@
/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.opensearch.rest;

import java.util.List;

class ProductReferences {

List<ProductReference> products;

public ProductReferences(List<ProductReference> products) {
super();
this.products = products;
}

public List<ProductReference> getProducts() {
return products;
}

}

0 comments on commit 532cea5

Please sign in to comment.