Merge "Issue #2049 Sister ticket to #753, WFS retrieval impl for MADIS" into development

Former-commit-id: 54045d6b9b [formerly c01ea33d5b] [formerly e4ecae9e7e [formerly f91e04da588da1714fd791ade2ecbfa826c9cdca]]
Former-commit-id: e4ecae9e7e
Former-commit-id: 58b11e075c
This commit is contained in:
Dustin Johnson 2013-05-30 17:11:19 -05:00 committed by Gerrit Code Review
commit 353630fcca
28 changed files with 939 additions and 184 deletions

View file

@ -24,6 +24,7 @@ export DATA_ARCHIVE_ROOT=/tmp/sbn
# setup db connections
export DB_ADDR=localhost
export DB_PORT=5432
export DB_DIALECT=org.hibernate.dialect.PostgreSQLDialect
# setup connection to qpid
export BROKER_ADDR=localhost

View file

@ -31,7 +31,7 @@
org.postgresql.Driver
</property>
<property name="dialect">
org.hibernate.dialect.PostgreSQLDialect
${db.dialect}
</property>
<property name="connection.url">
jdbc:postgresql://${db.addr}:${db.port}/metadata

View file

@ -100,12 +100,13 @@ wrapper.java.additional.qpid.1=-Dqpid.dest_syntax=BURL
# hibernate.cfg.xml cannot read from ENV variables but can read from Java system properties
wrapper.java.additional.db.1=-Ddb.addr=${DB_ADDR}
wrapper.java.additional.db.2=-Ddb.port=${DB_PORT}
wrapper.java.additional.db.3=-Ddc.db.name=${DC_DB_NAME}
wrapper.java.additional.db.4=-Dfxa.db.name=${FXA_DB_NAME}
wrapper.java.additional.db.5=-Dhm.db.name=${HM_DB_NAME}
wrapper.java.additional.db.6=-Dih.db.name=${IH_DB_NAME}
wrapper.java.additional.db.7=-Ddb.metadata.pool.min=${METADATA_POOL_MIN}
wrapper.java.additional.db.8=-Ddb.metadata.pool.max=${METADATA_POOL_MAX}
wrapper.java.additional.db.3=-Ddb.dialect=${DB_DIALECT}
wrapper.java.additional.db.4=-Ddc.db.name=${DC_DB_NAME}
wrapper.java.additional.db.5=-Dfxa.db.name=${FXA_DB_NAME}
wrapper.java.additional.db.6=-Dhm.db.name=${HM_DB_NAME}
wrapper.java.additional.db.7=-Dih.db.name=${IH_DB_NAME}
wrapper.java.additional.db.8=-Ddb.metadata.pool.min=${METADATA_POOL_MIN}
wrapper.java.additional.db.9=-Ddb.metadata.pool.max=${METADATA_POOL_MAX}
# site ID of EDEX for localization and site aware services
wrapper.java.additional.site.1=-Daw.site.identifier=${AW_SITE_IDENTIFIER}

View file

@ -27,4 +27,5 @@ export EDEX_DEBUG_PORT=5010
export EDEX_JMX_PORT=1621
export LOG4J_CONF=log4j-dataprovideragent.xml
export MGMT_PORT=9606
export DB_DIALECT=org.hibernatespatial.postgis.PostgisDialect

View file

@ -51,8 +51,13 @@ import com.raytheon.uf.common.serialization.ISerializableObject;
@XmlAccessorType(XmlAccessType.NONE)
public class ConfigLayer implements ISerializableObject {
// corresponds to the feature name/type
@XmlAttribute(name = "name", required = true)
private String name;
// corresponds to the feature namespace
@XmlAttribute(name = "namespace", required = true)
private String namespace;
@XmlElement(name = "minx", required = true)
private Double minx;
@ -68,7 +73,7 @@ public class ConfigLayer implements ISerializableObject {
@XmlElement(name = "crs", required = true)
private String crs;
@XmlElements({ @XmlElement(name = "parameter", type = Parameter.class, required = true) })
private List<Parameter> parameters;
@ -138,4 +143,12 @@ public class ConfigLayer implements ISerializableObject {
public String getCrs() {
return crs;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getNamespace() {
return namespace;
}
}

View file

@ -78,5 +78,32 @@ public class PointTime extends Time implements ISerializableObject, Serializable
public List<Date> getTimes() {
return times;
}
/**
* gets the most recent date
*/
public Date getEndDate() {
for (Date time: getTimes()) {
if (endDate == null) {
endDate = time;
} else if(endDate.before(time)) {
endDate = time;
}
}
return endDate;
}
/**
* gets the earliest date
*/
public Date getStartDate() {
for (Date time: getTimes()) {
if (startDate == null) {
startDate = time;
} else if(startDate.after(time)) {
startDate = time;
}
}
return startDate;
}
}

View file

@ -80,8 +80,7 @@ public class DatabaseSessionFactoryBean extends AnnotationSessionFactoryBean {
throws org.hibernate.AnnotationException {
Configuration config = getConfiguration();
AnnotationConfiguration tmp = loadNewConfigForClasses(classes);
return tmp.generateSchemaCreationScript(Dialect.getDialect(config
.getProperties()));
return tmp.generateSchemaCreationScript(config.buildSettings().getDialect());
}
/**
@ -99,8 +98,7 @@ public class DatabaseSessionFactoryBean extends AnnotationSessionFactoryBean {
throws org.hibernate.AnnotationException {
Configuration config = getConfiguration();
AnnotationConfiguration tmp = loadNewConfigForClasses(classes);
return tmp.generateDropSchemaScript(Dialect.getDialect(config
.getProperties()));
return tmp.generateDropSchemaScript(config.buildSettings().getDialect());
}
private AnnotationConfiguration loadNewConfigForClasses(

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<serviceConfig name="WFS">
<!-- Date format used by WFS providers -->
<dateConfig>
<format>yyyy-MM-dd'T'HH:mm:ss.SSSZ</format>
</dateConfig>
<constant name="BLANK" value=""/>
<constant name="UNKNOWN" value="unknown"/>
<constant name="NONE" value="NONE"/>
<constant name="REQUEST_HEADER" value="request"/>
<constant name="CAP_PARAM" value="getcapabilities"/>
<constant name="DESC_PARAM" value="describefeaturetype"/>
<constant name="GET_PARAM" value="getfeature"/>
<constant name="OUTFORMAT_HEADER" value="outputformat"/>
<constant name="RESTYPE_HEADER" value="resulttype"/>
<constant name="PROPNAME_HEADER" value="propertyname"/>
<constant name="MAXFEAT_HEADER" value="maxfeatures"/>
<constant name="SRSNAME_HEADER" value="srsname"/>
<constant name="TYPENAME_HEADER" value="typename"/>
<constant name="FEATID_HEADER" value="featureid"/>
<constant name="FILTER_HEADER" value="filter"/>
<constant name="BBOX_HEADER" value="bbox"/>
<constant name="SORTBY_HEADER" value="sortby"/>
<constant name="NS_HEADER" value="namespace"/>
<constant name="WFS" value="wfs"/>
<constant name="VERSION" value="1.1.0"/>
<constant name="PORT_HEADER" value="http://"/>
<constant name="PORT" value="80"/>
<constant name="COMMA" value=","/>
</serviceConfig>

View file

@ -18,7 +18,7 @@
</provider>
<agent xsi:type="ogcAgent" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dateFormat>HHddMMMyyyy</dateFormat>
<layer name="madis">
<layer name="madis" namespace="http://madis.edex.uf.raytheon.com">
<!-- Geographic constraint of madis layer data -->
<minx>-120.0</minx>
<maxx>-70.0</maxx>

View file

@ -30,7 +30,11 @@ Require-Bundle: com.raytheon.uf.common.status;bundle-version="1.12.1174",
com.raytheon.uf.edex.event;bundle-version="1.0.0",
com.raytheon.uf.common.stats;bundle-version="1.0.0",
com.raytheon.uf.edex.decodertools;bundle-version="1.12.1174",
com.raytheon.uf.edex.registry.ebxml;bundle-version="1.0.0"
com.raytheon.uf.edex.registry.ebxml;bundle-version="1.0.0",
com.raytheon.uf.common.dataplugin.madis;bundle-version="1.0.0",
com.raytheon.uf.edex.plugin.madis.ogc;bundle-version="1.0.0",
net.opengis;bundle-version="1.0.2",
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: com.raytheon.uf.edex.datadelivery.retrieval;

View file

@ -23,6 +23,7 @@ package com.raytheon.uf.edex.datadelivery.retrieval;
import java.util.List;
import com.raytheon.uf.common.datadelivery.registry.AdhocSubscription;
import com.raytheon.uf.common.datadelivery.registry.Parameter;
import com.raytheon.uf.common.datadelivery.registry.PendingSubscription;
import com.raytheon.uf.common.datadelivery.registry.Provider.ServiceType;
import com.raytheon.uf.common.datadelivery.registry.Subscription;
@ -111,4 +112,29 @@ public abstract class RetrievalGenerator {
return null;
}
}
/**
* clone the param
*
* @param original
* parameter
* @return
*/
protected Parameter processParameter(Parameter origParm) {
Parameter param = new Parameter();
param.setName(origParm.getName());
param.setBaseType(origParm.getBaseType());
param.setDataType(origParm.getDataType());
param.setDefinition(origParm.getDefinition());
param.setFillValue(origParm.getFillValue());
param.setLevelType(origParm.getLevelType());
param.setMissingValue(origParm.getMissingValue());
param.setProviderName(origParm.getProviderName());
param.setUnits(origParm.getUnits());
return param;
}
}

View file

@ -33,6 +33,7 @@ import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
* ------------ ---------- ----------- --------------------------
* Jan 16, 2011 dhladky Initial creation
* Aug 14, 2012 1022 djohnson Remove redundant public modifiers.
* May 12, 2013 753 dhladky Madis additions
*
* </pre>
*

View file

@ -25,6 +25,7 @@ import java.util.Map;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
import com.raytheon.uf.common.dataplugin.madis.MadisRecord;
import com.raytheon.uf.common.serialization.ISerializableObject;
/**
@ -38,35 +39,49 @@ import com.raytheon.uf.common.serialization.ISerializableObject;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 19, 2012 bsteffen Initial javadoc
* May 12, 2013 753 dhladky Added support for Madis
*
* </pre>
*
* @author unknown
* @version 1.0
*/
public abstract class AbstractMetadataAdapter implements ISerializableObject {
public abstract class AbstractMetadataAdapter<RecordKey> implements ISerializableObject {
protected PluginDataObject[] pdos;
protected RetrievalAttribute attXML;
protected static Map<String, String[]> parameterMap = new HashMap<String, String[]>();
public static AbstractMetadataAdapter getMetadataAdapter(Class<?> clazz,
public static AbstractMetadataAdapter<?> getMetadataAdapter(Class<?> clazz,
RetrievalAttribute attXML) throws InstantiationException {
AbstractMetadataAdapter adapter = null;
AbstractMetadataAdapter<?> adapter = null;
if (clazz == GridRecord.class) {
adapter = new GridMetadataAdapter(attXML);
} else if (clazz == MadisRecord.class) {
adapter = new MadisMetadataAdapter(attXML);
} else {
throw new IllegalArgumentException("Did not receive a class recognzed for retreival.");
}
return adapter;
}
public PluginDataObject getRecord(int index) {
if (pdos != null && index < pdos.length) {
return pdos[index];
}
return null;
// setup an individual record from the direct plugin translation
public abstract PluginDataObject getRecord(RecordKey o);
// set the size of the PDO array to return
public abstract void setPdos(int size);
/**
* get the PDO list
* @return
*/
public PluginDataObject[] getPdos() {
return pdos;
}
}

View file

@ -28,6 +28,7 @@ import com.raytheon.edex.util.Util;
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
import com.raytheon.uf.common.datadelivery.registry.Parameter;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
import com.raytheon.uf.common.dataplugin.level.Level;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
@ -45,13 +46,14 @@ import com.raytheon.uf.edex.datadelivery.retrieval.util.ResponseProcessingUtilit
* ------------ ---------- ----------- --------------------------
* Nov 19, 2012 bsteffen Initial javadoc
* Feb 07, 2013 1543 djohnson Allow package-level overriding of methods for mocking in tests.
* May 12, 2013 753 dhladky Altered to be more flexible with other types
*
* </pre>
*
* @author unknown
* @version 1.0
*/
public class GridMetadataAdapter extends AbstractMetadataAdapter {
public class GridMetadataAdapter extends AbstractMetadataAdapter<Integer> {
public GridMetadataAdapter(RetrievalAttribute attXML)
throws InstantiationException {
@ -79,8 +81,7 @@ public class GridMetadataAdapter extends AbstractMetadataAdapter {
}
}
pdos = new GridRecord[size];
setPdos(size);
GridCoverage gridCoverage = ((GriddedCoverage) attXML.getCoverage())
.getRequestGridCoverage();
@ -243,4 +244,17 @@ public class GridMetadataAdapter extends AbstractMetadataAdapter {
return vals;
}
@Override
public PluginDataObject getRecord(Integer index) {
if (pdos != null && index < pdos.length) {
return pdos[index];
}
return null;
}
@Override
public void setPdos(int size) {
pdos = new GridRecord[size];
}
}

View file

@ -0,0 +1,44 @@
package com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.madis.MadisRecord;
import com.raytheon.uf.edex.plugin.madis.ogc.feature.Madis;
/**
*
* Convert RetrievalAttribute to MadisRecords.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky Initial javadoc
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class MadisMetadataAdapter extends AbstractMetadataAdapter<Madis> {
public MadisMetadataAdapter(RetrievalAttribute attXML)
throws InstantiationException {
this.attXML = attXML;
}
@Override
public PluginDataObject getRecord(Madis madis) {
return madis.getRecord();
}
@Override
public void setPdos(int size) {
pdos = new MadisRecord[size];
}
}

View file

@ -45,6 +45,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.request.RequestBuilder;
* Aug 14, 2012 1022 djohnson Throw exception if invalid OpenDAP grid coordinates specified,
* make immutable, use StringBuilder instead of StringBuffer.
* Dec 10, 2012 1259 bsteffen Switch Data Delivery from LatLon to referenced envelopes.
* May 12, 2013 753 dhladky address field
*
* </pre>
*
@ -239,4 +240,5 @@ class OpenDAPRequestBuilder extends RequestBuilder {
public RetrievalAttribute getAttribute() {
return getRetrievalAttribute();
}
}

View file

@ -489,30 +489,6 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
}
/**
* clone the param
*
* @param original
* parameter
* @return
*/
private Parameter processParameter(Parameter origParm) {
Parameter param = new Parameter();
param.setName(origParm.getName());
param.setBaseType(origParm.getBaseType());
param.setDataType(origParm.getDataType());
param.setDefinition(origParm.getDefinition());
param.setFillValue(origParm.getFillValue());
param.setLevelType(origParm.getLevelType());
param.setMissingValue(origParm.getMissingValue());
param.setProviderName(origParm.getProviderName());
param.setUnits(origParm.getUnits());
return param;
}
/**
* Process sequences of hours for separate retrieval
*

View file

@ -0,0 +1,95 @@
package com.raytheon.uf.edex.datadelivery.retrieval.response;
import java.util.ArrayList;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import net.opengis.gml.v_3_1_1.AbstractFeatureType;
import net.opengis.gml.v_3_1_1.FeaturePropertyType;
import net.opengis.wfs.v_1_1_0.FeatureCollectionType;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.serialization.SerializationUtil;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.DataTime;
/**
*
* Translate WFS retrievals into PDOs
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky Initial javadoc
*
* </pre>
*
* @author unknown
* @version 1.0
*/
public class WfsTranslator extends RetrievalTranslator {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsTranslator.class);
WfsTranslator(RetrievalAttribute attXML, String className)
throws InstantiationException {
super(attXML, className);
}
public WfsTranslator(RetrievalAttribute attXML) throws InstantiationException {
super(attXML);
}
@Override
protected int getSubsetNumTimes() {
// TODO Auto-generated method stub
return 0;
}
@Override
protected int getSubsetNumLevels() {
// TODO Auto-generated method stub
return 0;
}
@Override
protected ArrayList<DataTime> getTimes() {
// TODO Auto-generated method stub
return null;
}
/**
* XML string into abstract features then to PDOs
* @param payload
* @return
*/
public PluginDataObject[] asPluginDataObjects(String payload) {
try {
FeatureCollectionType featureList = SerializationUtil.unmarshalFromXml(FeatureCollectionType.class, payload);
if (featureList.getNumberOfFeatures().intValue() > 0) {
int i = 0;
metadataAdapter.setPdos(featureList.getNumberOfFeatures().intValue());
for (FeaturePropertyType type : featureList.getFeatureMember()) {
JAXBElement<? extends AbstractFeatureType> feature = type.getFeature();
metadataAdapter.getPdos()[i] = metadataAdapter.getRecord(feature);
i++;
}
}
} catch (JAXBException e) {
statusHandler.handle(Priority.PROBLEM, "Can't de-serialize FeatureCollection", e);
}
return null;
}
}

View file

@ -22,6 +22,7 @@ package com.raytheon.uf.edex.datadelivery.retrieval.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.regex.Pattern;
import com.raytheon.edex.colormap.ColorMapManager;
import com.raytheon.uf.common.comm.ProxyConfiguration;
@ -45,6 +46,7 @@ import dods.dap.DConnect;
* ------------ ---------- ----------- --------------------------
* Jun 28, 2012 819 djohnson Initial creation
* Apr 01, 2013 1786 mpduff Pulled proxy settings out to util class.
* May 12, 2013 753 dhladky Expanded for use with other connection types
*
* </pre>
*
@ -60,7 +62,7 @@ public class ConnectionUtil {
+ File.separator + "proxy.properties";
static ConnectionUtil instance = new ConnectionUtil();
static volatile boolean initialized;
private ProxyConfiguration proxySettings;
@ -107,6 +109,8 @@ public class ConnectionUtil {
return instance.getProxyInformation();
}
private static synchronized void initialize() {
ProxyConfiguration proxyInformation = instance.getProxyInformation();

View file

@ -52,7 +52,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.mapping.PluginRouteList;
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 26, 2012 1367 dhladky Common plugin route persistance
* Nov 26, 2012 1367 dhladky Common plugin route persistence
*
* </pre>
*

View file

@ -0,0 +1,47 @@
package com.raytheon.uf.edex.datadelivery.retrieval.util;
import com.raytheon.uf.common.comm.HttpClient;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
*
* WFS Connection.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky created.
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class WfsConnectionUtil {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsConnectionUtil.class);
public static String wfsConnect(String address, String message) {
String xmlResponse = null;
// sets up any proxy info that might be necessary
ConnectionUtil.getProxyParameters();
HttpClient http = HttpClient.getInstance();
try {
xmlResponse = http.post(address, message);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, "Couldn't connect to WFS server: "+address+" with posted message of: "+message, e);
}
return xmlResponse;
}
}

View file

@ -1,76 +0,0 @@
package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
import java.util.HashMap;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.edex.datadelivery.retrieval.adapters.RetrievalAdapter;
import com.raytheon.uf.edex.datadelivery.retrieval.interfaces.IRetrievalRequestBuilder;
import com.raytheon.uf.edex.datadelivery.retrieval.interfaces.IRetrievalResponse;
import com.raytheon.uf.edex.datadelivery.retrieval.response.RetrievalResponse;
/**
* WFS OGC Provider Retrieval Adapter
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 07, 2011 dhladky Initial creation
* Jul 25, 2012 955 djohnson Moved to wfs specific package.
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class WFSRetrievalAdapter extends RetrievalAdapter {
public WFSRetrievalAdapter() {
}
@Override
public IRetrievalRequestBuilder createRequestMessage(
RetrievalAttribute prxml) {
// TODO Auto-generated method stub
return null;
}
@Override
public HashMap<String, PluginDataObject[]> processResponse(
IRetrievalResponse response) {
// TODO Auto-generated method stub
return null;
}
@Override
public RetrievalResponse performRequest(
IRetrievalRequestBuilder request) {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -1,54 +0,0 @@
package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
import java.util.List;
import com.raytheon.uf.common.datadelivery.registry.Provider.ServiceType;
import com.raytheon.uf.common.datadelivery.registry.Subscription;
import com.raytheon.uf.common.datadelivery.registry.SubscriptionBundle;
import com.raytheon.uf.common.datadelivery.retrieval.xml.Retrieval;
import com.raytheon.uf.edex.datadelivery.retrieval.RetrievalGenerator;
import com.raytheon.uf.edex.datadelivery.retrieval.adapters.RetrievalAdapter;
/**
*
* WFS Retrieval Generator.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 25, 2012 955 djohnson Moved to wfs specific package.
* Nov 19, 2012 1166 djohnson Clean up JAXB representation of registry objects.
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
class WFSRetrievalGenerator extends RetrievalGenerator {
WFSRetrievalGenerator() {
super(ServiceType.WFS);
}
@Override
public List<Retrieval> buildRetrieval(SubscriptionBundle bundle) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* {@inheritDoc}
*/
@Override
protected RetrievalAdapter getServiceRetrievalAdapter() {
return new WFSRetrievalAdapter();
}
@Override
protected Subscription removeDuplicates(Subscription sub) {
throw new UnsupportedOperationException("Not implemented");
}
}

View file

@ -0,0 +1,164 @@
package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.geotools.geometry.jts.ReferencedEnvelope;
import com.raytheon.uf.common.datadelivery.registry.Coverage;
import com.raytheon.uf.common.datadelivery.registry.Provider.ServiceType;
import com.raytheon.uf.common.datadelivery.registry.Time;
import com.raytheon.uf.common.datadelivery.retrieval.util.HarvesterServiceManager;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.datadelivery.retrieval.xml.ServiceConfig;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.edex.datadelivery.retrieval.request.RequestBuilder;
/**
*
* WFS Request Builder.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky created.
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class WfsRequestBuilder extends RequestBuilder {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsRequestBuilder.class);
protected static ServiceConfig wfsServiceConfig;
public static final String separator = getServiceConfig().getConstantValue("COMMA");
private final String wfsURL;
WfsRequestBuilder(WfsRetrievalAdapter adapter,
RetrievalAttribute attXML) {
super(attXML);
// Create URL
// this works in this order
StringBuilder buffer = new StringBuilder();
// apply the base WFS service URL
buffer.append(adapter.getProviderRetrievalXMl().getConnection()
.getUrl());
buffer.append("?");
// apply the feature you are trying to retrieve
buffer.append(getRetrievalAttribute().getParameter().getProviderName());
// process the coverage bounding box
buffer.append(processCoverage());
// process the time range you are trying to retrieve
buffer.append(processTime(getRetrievalAttribute().getTime()));
this.wfsURL = buffer.toString().trim();
}
private static ThreadLocal<SimpleDateFormat> ogcDateFormat = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
SimpleDateFormat sdf = new SimpleDateFormat(getServiceConfig()
.getDateConfig().getFormats().get(0));
return sdf;
}
};
@Override
public String processTime(Time time) {
try {
if (time.getEndDate() != null && time.getStartDate() != null) {
Date sDate = time.getStartDate();
Date eDate = time.getEndDate();
String endDateString = ogcDateFormat.get().format(eDate);
String startDateString = ogcDateFormat.get().format(sDate);
StringBuilder sb = new StringBuilder();
sb.append("&TIME=");
sb.append(startDateString);
sb.append("/");
if (!endDateString.equals(startDateString)) {
sb.append(endDateString);
}
return sb.toString();
}
} catch (Exception e) {
statusHandler.error("Couldn't parse Time object." + e);
}
// no times, return blank
return getServiceConfig().getConstantValue("BLANK");
}
@Override
public String processCoverage() {
// &srsName=crs:84&bbox=-100.0,41.0,-98.0,43.0
StringBuilder sb = new StringBuilder();
Coverage coverage = getRetrievalAttribute().getCoverage();
if (coverage != null) {
ReferencedEnvelope re = coverage.getRequestEnvelope();
// manage the box
double lowerLon = re.getMinX();
double lowerLat = re.getMinY();
double upperLon = re.getMaxX();
double upperLat = re.getMaxY();
sb.append("&srsName=");
sb.append(coverage.getEnvelope().getCoordinateReferenceSystem()
.getName());
sb.append("&bbox=");
sb.append(lowerLon);
sb.append(separator);
sb.append(lowerLat);
sb.append(separator);
sb.append(upperLon);
sb.append(separator);
sb.append(upperLat);
return sb.toString();
}
return getServiceConfig().getConstantValue("BLANK");
}
@Override
public String getRequest() {
return wfsURL;
}
@Override
public RetrievalAttribute getAttribute() {
return getRetrievalAttribute();
}
/**
* Get the instance of the service config
* @return
*/
private static ServiceConfig getServiceConfig() {
if (wfsServiceConfig == null) {
wfsServiceConfig = HarvesterServiceManager.getInstance()
.getServiceConfig(ServiceType.WFS);
}
return wfsServiceConfig;
}
}

View file

@ -0,0 +1,141 @@
package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.event.EventBus;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.CollectionUtil;
import com.raytheon.uf.edex.datadelivery.retrieval.RetrievalEvent;
import com.raytheon.uf.edex.datadelivery.retrieval.adapters.RetrievalAdapter;
import com.raytheon.uf.edex.datadelivery.retrieval.interfaces.IRetrievalRequestBuilder;
import com.raytheon.uf.edex.datadelivery.retrieval.interfaces.IRetrievalResponse;
import com.raytheon.uf.edex.datadelivery.retrieval.response.RetrievalResponse;
import com.raytheon.uf.edex.datadelivery.retrieval.response.WfsTranslator;
import com.raytheon.uf.edex.datadelivery.retrieval.util.WfsConnectionUtil;
/**
* WFS OGC Provider Retrieval Adapter
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 07, 2011 dhladky Initial creation
* Jul 25, 2012 955 djohnson Moved to wfs specific package.
* May 12, 2013 753 dhladky implemented.
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class WfsRetrievalAdapter extends RetrievalAdapter {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsRetrievalAdapter.class);
private Pattern splitter = Pattern.compile("?");
@Override
public IRetrievalRequestBuilder createRequestMessage(
RetrievalAttribute attXML) {
WfsRequestBuilder reqBuilder = new WfsRequestBuilder(this, attXML);
return reqBuilder;
}
@Override
public Map<String, PluginDataObject[]> processResponse(
IRetrievalResponse response) throws TranslationException {
Map<String, PluginDataObject[]> map = new HashMap<String, PluginDataObject[]>();
WfsTranslator translator;
try {
translator = getWfsTranslator(response.getAttribute());
} catch (InstantiationException e) {
throw new TranslationException(
"Unable to instantiate a required class!", e);
}
String payload = (String) response.getPayLoad();
try {
if (payload != null) {
PluginDataObject[] pdos = translator
.asPluginDataObjects(payload);
if (!CollectionUtil.isNullOrEmpty(pdos)) {
String pluginName = pdos[0].getPluginName();
map.put(pluginName,
CollectionUtil.combine(PluginDataObject.class,
map.get(pluginName), pdos));
}
}
} catch (ClassCastException e) {
throw new TranslationException(e);
}
return map;
}
@Override
public RetrievalResponse performRequest(
IRetrievalRequestBuilder request) {
String xmlMessage = null;
try {
// break url into CGI parameters and address
splitter.split(request.getRequest());
String[] parts = splitter.split(request.getRequest());
xmlMessage = WfsConnectionUtil.wfsConnect(parts[0], parts[1]);
} catch (Exception e) {
statusHandler.handle(Priority.ERROR, e.getLocalizedMessage(), e);
EventBus.publish(new RetrievalEvent(e.getMessage()));
}
RetrievalResponse pr = new WfsRetrievalResponse(request.getAttribute());
pr.setPayLoad(xmlMessage);
return pr;
}
/**
* @param attribute
* @return
*/
WfsTranslator getWfsTranslator(RetrievalAttribute attribute)
throws InstantiationException {
return new WfsTranslator(attribute);
}
}

View file

@ -0,0 +1,227 @@
package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.annotations.VisibleForTesting;
import com.raytheon.uf.common.datadelivery.registry.Coverage;
import com.raytheon.uf.common.datadelivery.registry.DataSetMetaData;
import com.raytheon.uf.common.datadelivery.registry.Parameter;
import com.raytheon.uf.common.datadelivery.registry.PointDataSetMetaData;
import com.raytheon.uf.common.datadelivery.registry.PointTime;
import com.raytheon.uf.common.datadelivery.registry.Provider.ProviderType;
import com.raytheon.uf.common.datadelivery.registry.Provider.ServiceType;
import com.raytheon.uf.common.datadelivery.registry.Subscription;
import com.raytheon.uf.common.datadelivery.registry.SubscriptionBundle;
import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers;
import com.raytheon.uf.common.datadelivery.retrieval.xml.Retrieval;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.edex.datadelivery.retrieval.RetrievalGenerator;
import com.raytheon.uf.edex.datadelivery.retrieval.adapters.RetrievalAdapter;
/**
*
* WFS Retrieval Generator.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 25, 2012 955 djohnson Moved to wfs specific package.
* Nov 19, 2012 1166 djohnson Clean up JAXB representation of registry objects.
* May 12, 2013 753 dhladky Implemented
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
class WfsRetrievalGenerator extends RetrievalGenerator {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsRetrievalGenerator.class);
WfsRetrievalGenerator() {
super(ServiceType.WFS);
}
@Override
public List<Retrieval> buildRetrieval(SubscriptionBundle bundle) {
List<Retrieval> retrievals = Collections.emptyList();
switch (bundle.getDataType()) {
case POINT:
retrievals = getPointRetrievals(bundle);
break;
default:
statusHandler.error("Grid DATA WFS NOT YET IMPLEMENTED");
throw new IllegalArgumentException("Grid DATA WFS NOT YET IMPLEMENTED");
}
return retrievals;
}
/**
* create the grid type retrievals
*
* @param bundle
* @return
*/
private List<Retrieval> getPointRetrievals(SubscriptionBundle bundle) {
List<Retrieval> retrievals = new ArrayList<Retrieval>();
Subscription sub = bundle.getSubscription();
sub = removeDuplicates(sub);
if (sub != null) {
PointTime subTime = (PointTime) sub.getTime();
String retrievalUrl = getRetrievalUrl(sub);
sub.setUrl(retrievalUrl);
if (sub.getUrl() == null) {
statusHandler
.info("Skipping subscription that is unfulfillable with the current metadata.");
return Collections.emptyList();
}
// with point data they all have the same data
Parameter param = sub.getParameter().get(0);
Retrieval retrieval = getRetrieval(sub, bundle,
param, subTime);
retrievals.add(retrieval);
}
return retrievals;
}
/**
* Determines the retrieval URL
*
* @param subscription
* the subscription
* @return the url for retrieval or null if no retrieval should take place
*/
private static String getRetrievalUrl(Subscription subscription) {
String url = subscription.getUrl();
DataSetMetaData result = null;
try {
result = DataDeliveryHandlers.getDataSetMetaDataHandler().getById(
url);
if (result == null) {
throw new RegistryHandlerException(
"Unable to find the dataset by id from its unique url!",
new NullPointerException("DataSetMetaData"));
}
if (satisfiesSubscriptionCriteria(subscription, result)) {
return url;
}
} catch (RegistryHandlerException e) {
statusHandler.handle(Priority.PROBLEM,
"Unable to find the dataset by id from its unique url!", e);
}
return null;
}
/**
* Determines whether a subscription can be satisified by the dataset
* metadata.
*
* @param subscription
* the subscription
* @param dsmd
* the dataset metadata
* @return true if the datasetmetadata will satisfy the subscription
*/
@VisibleForTesting
static boolean satisfiesSubscriptionCriteria(Subscription subscription,
DataSetMetaData dsmd) {
if (dsmd instanceof PointDataSetMetaData) {
PointDataSetMetaData data = (PointDataSetMetaData) dsmd;
//TODO determine some check for validity of point data sets
return true;
}
return false;
}
/**
* Get the retrieval
*
* @param sub
* @param bundle
* @param param
* @param level
* @param Time
* @return
*/
private Retrieval getRetrieval(Subscription sub, SubscriptionBundle bundle,
Parameter param, PointTime time) {
Retrieval retrieval = new Retrieval();
retrieval.setSubscriptionName(sub.getName());
retrieval.setServiceType(getServiceType());
retrieval.setConnection(bundle.getConnection());
retrieval.getConnection().setUrl(sub.getUrl());
retrieval.setOwner(sub.getOwner());
retrieval.setSubscriptionType(getSubscriptionType(sub));
retrieval.setNetwork(sub.getRoute());
// Coverage and type processing
Coverage cov = sub.getCoverage();
ProviderType pt = null;
if (cov instanceof Coverage){
pt = ProviderType.POINT;
retrieval.setProviderType(pt);
} else {
throw new UnsupportedOperationException(
"WFS retrieval does not yet support coverages other than Point. ");
}
// Attribute processing
RetrievalAttribute att = new RetrievalAttribute();
Parameter lparam = processParameter(param);
att.setCoverage(cov);
lparam.setLevels(param.getLevels());
att.setTime(time);
att.setParameter(lparam);
att.setSubName(retrieval.getSubscriptionName());
att.setPlugin(pt.getPlugin());
att.setProvider(sub.getProvider());
retrieval.addAttribute(att);
return retrieval;
}
/**
* {@inheritDoc}
*/
@Override
protected RetrievalAdapter getServiceRetrievalAdapter() {
return new WfsRetrievalAdapter();
}
@Override
protected Subscription removeDuplicates(Subscription sub) {
throw new UnsupportedOperationException("Not implemented");
}
}

View file

@ -0,0 +1,51 @@
package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.edex.datadelivery.retrieval.response.RetrievalResponse;
/**
* {@link RetrievalResponse} for WFS.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky Initial creation
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
@DynamicSerialize
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class WfsRetrievalResponse extends RetrievalResponse {
@XmlElement
private String payload;
public WfsRetrievalResponse(RetrievalAttribute attribute) {
}
@Override
public void setPayLoad(Object payLoad) {
this.payload = (String)payload;
}
@Override
public String getPayLoad() {
return payload;
}
}

View file

@ -36,6 +36,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.ServiceFactory;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 25, 2012 955 djohnson Initial creation
* May 12, 2013 753 dhladky implementation
*
* </pre>
*
@ -75,7 +76,7 @@ public class WfsServiceFactory implements ServiceFactory {
*/
@Override
public RetrievalGenerator getRetrievalGenerator() {
return new WFSRetrievalGenerator();
return new WfsRetrievalGenerator();
}
}