Issue #2101 Subscription retrieval for WFS (MADIS) follow on of #1763, #2062 for 13.6.1

Change-Id: I5942d35c77eaa0232147581381e1ff96c690cc03

Former-commit-id: 00fcd53e94c1ff71d65c42b5f7644f653a1fd179
This commit is contained in:
Dave Hladky 2013-06-03 16:09:24 -05:00
parent 180e01cf4c
commit 776bbbba21
41 changed files with 1641 additions and 703 deletions

View file

@ -227,10 +227,13 @@
<include>nwsauth-request.xml</include>
<include>grid-staticdata-process.xml</include>
<include>grid-common.xml</include>
<include>grid-metadata.xml</include>
<include>gridcoverage-.*.xml</include>
<include>parameter-common.xml</include>
<include>pointdata-common.xml</include>
<include>obs-common.xml</include>
<include>madis-common.xml</include>
<include>madis-metadata.xml</include>
<include>level-common.xml</include>
<include>persist-ingest.xml</include>
<include>management-common.xml</include>

View file

@ -398,6 +398,7 @@ public class HttpClient {
private HttpClient() {
}
private org.apache.http.client.HttpClient getHttpsInstance() {
return HttpsHolder.sslClient;
}
@ -1146,7 +1147,7 @@ public class HttpClient {
new AuthScope(host, port),
new UsernamePasswordCredentials(username, password));
}
/**
* @param httpsConfiguration
* the httpsConfiguration to set
@ -1161,4 +1162,5 @@ public class HttpClient {
public IHttpsConfiguration getHttpsConfiguration() {
return httpsConfiguration;
}
}

View file

@ -25,6 +25,7 @@ import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.serialization.ISerializableObject;
@ -42,6 +43,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
* Jan 17, 2011 191 dhladky Initial creation
* Jun 28, 2012 819 djohnson Remove proxy information.
* Jul 24, 2012 955 djohnson Add copy constructor.
* Jun 11, 2013 1763 dhladky Added Encryption type
*
* </pre>
*
@ -69,6 +71,7 @@ public class Connection implements ISerializableObject, Serializable {
setPassword(connection.getPassword());
setUrl(connection.getUrl());
setUserName(connection.getUserName());
setEncryption(connection.getEncryption());
}
@XmlElement(name = "userName")
@ -78,6 +81,10 @@ public class Connection implements ISerializableObject, Serializable {
@XmlElement(name = "password")
@DynamicSerializeElement
private String password;
@XmlElement(name = "encryption")
@DynamicSerializeElement
private Encryption encryption;
@XmlElement(name = "url")
@DynamicSerializeElement
@ -100,11 +107,43 @@ public class Connection implements ISerializableObject, Serializable {
}
public String getPassword() {
return password;
if (password != null) {
return encryption.decrypt(password);
}
return null;
}
public void setUserName(String userName) {
this.userName = userName;
}
@XmlEnum
public enum Encryption {
// will have a map of these eventually
CLEAR(Encryption.CLEAR_VALUE);
private static final String CLEAR_VALUE = "CLEAR";
private final String displayString;
private Encryption(String displayString) {
this.displayString = displayString;
}
// clear text for now so nothing happens here
public String decrypt(String password) {
return password;
}
}
public Encryption getEncryption() {
return encryption;
}
public void setEncryption(Encryption encryption) {
this.encryption = encryption;
}
}

View file

@ -21,28 +21,24 @@ import com.raytheon.uf.common.time.domain.api.IDuration;
/**
*
* Represents a service interface in ebRIM. Matches interface as defined in WSDL
* 2.
*
*
* <p>
* Java class for ServiceInterfaceType complex type.
*
* <p>
* The following schema fragment specifies the expected content contained within
* this class.
* Provider Object
*
* <pre>
* &lt;complexType name="ServiceInterfaceType">
* &lt;complexContent>
* &lt;extension base="{urn:oasis:names:tc:ebxml-regrep:xsd:rim:4.0}RegistryObjectType">
* &lt;/extension>
* &lt;/complexContent>
* &lt;/complexType>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 16, 2012 dhladky Initial creation
* jun 11, 2013 2101 dhladky Updated for username/password DPA exchanges
*
* </pre>
*
*
* @author dhladky
* @version 1.0
*/
@XmlRootElement(name = "provider")
@XmlAccessorType(XmlAccessType.NONE)
@DynamicSerialize
@ -68,9 +64,9 @@ public class Provider implements ISerializableObject {
*/
public enum ServiceType {
// TODO: Only OPENDAP has the correct amounts
OPENDAP(5000, BYTES_IN_FLOAT), WCS(5000, BYTES_IN_FLOAT), WFS(5000,
BYTES_IN_FLOAT), WMS(5000, BYTES_IN_FLOAT), WXXM(5000,
// TODO: Only OPENDAP and WFS have the correct amounts
OPENDAP(5000, BYTES_IN_FLOAT), WCS(5000, BYTES_IN_FLOAT), WFS(2411724,
OneByOneBox), WMS(5000, BYTES_IN_FLOAT), WXXM(5000,
BYTES_IN_FLOAT);
private final long requestOverheadInBytes;
@ -87,10 +83,33 @@ public class Provider implements ISerializableObject {
return bytesPerParameterRequest * numberOfPoints
+ requestOverheadInBytes;
}
/**
* Takes in a WFS request and gives you a nominal byte size based
* on the size in lat/lon of the bounding box and the interval in multiples of
* 5 min intervals.
*
* timeSpan ~ minutes
* latSpan ~ span in degrees of lat for bounding box
* lonSpan ~ span in degrees of lon for bounding box
*
* @param latSpan
* @param lonSpan
* @param timeSpan
* @return
*/
public long getRequestBytesPerLatLonBoxAndTime(double latSpan,
double lonSpan, int timeSpan) {
// increments are in 5 minutes so 5/5 = 1
return (long) (latSpan * lonSpan * timeSpan/5 * requestOverheadInBytes);
}
}
private static final Integer BYTES_IN_FLOAT = Float.SIZE / Byte.SIZE;
/** a one degree by one degree box **/
private static final Integer OneByOneBox = 1;
@XmlAttribute(name = "name", required = true)
@DynamicSerializeElement
@SlotAttribute

View file

@ -27,14 +27,17 @@ import org.geotools.geometry.jts.ReferencedEnvelope;
import com.raytheon.uf.common.datadelivery.registry.Coverage;
import com.raytheon.uf.common.datadelivery.registry.DataSet;
import com.raytheon.uf.common.datadelivery.registry.Ensemble;
import com.raytheon.uf.common.datadelivery.registry.EnvelopeUtils;
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet;
import com.raytheon.uf.common.datadelivery.registry.Levels;
import com.raytheon.uf.common.datadelivery.registry.Parameter;
import com.raytheon.uf.common.datadelivery.registry.PointTime;
import com.raytheon.uf.common.datadelivery.registry.Provider.ServiceType;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
import com.raytheon.uf.common.util.CollectionUtil;
import com.vividsolutions.jts.geom.Coordinate;
/**
* Data Structure for calculating Data Set Size.
@ -49,6 +52,7 @@ import com.raytheon.uf.common.util.CollectionUtil;
* Aug 12, 2012 1022 djohnson Stop coordinates on GriddedCoverage from being corrupted.
* Oct 31, 2012 1278 mpduff Clarified a Javadoc comment.
* Dec 10, 2012 1259 bsteffen Switch Data Delivery from LatLon to referenced envelopes.
* Jun 11, 2013 2021 dhladky WFS semi-scientific sizing.
*
* </pre>
*
@ -68,16 +72,33 @@ public class DataSizeUtils {
public static long calculateSize(RetrievalAttribute ra, ServiceType st) {
if (ra.getCoverage() instanceof GriddedCoverage) {
GriddedCoverage griddedCov = (GriddedCoverage) ra.getCoverage();
int nx = griddedCov.getGridCoverage().getNx();
int ny = griddedCov.getGridCoverage().getNy();
if (st == ServiceType.OPENDAP) {
if (ra.getCoverage() instanceof GriddedCoverage) {
GriddedCoverage griddedCov = (GriddedCoverage) ra.getCoverage();
int nx = griddedCov.getGridCoverage().getNx();
int ny = griddedCov.getGridCoverage().getNy();
long l = st.getRequestBytesPerParameterPerLevel(nx * ny);
long l = st.getRequestBytesPerParameterPerLevel(nx * ny);
l = l / bytesPerKilobyte;
l = l / bytesPerKilobyte;
return l;
} else {
throw new IllegalStateException(
"Couldn't calculate the retrieval size for a retrieval of type "
+ st.name() + "!");
}
} else if (st == ServiceType.WFS) {
ReferencedEnvelope re = ra.getCoverage().getRequestEnvelope();
Coordinate ur = EnvelopeUtils.getUpperRightLatLon(re);
Coordinate ll = EnvelopeUtils.getLowerLeftLatLon(re);
double lonSpan = Math.abs(ll.x - ur.x);
double latSpan = Math.abs(ll.y - ur.y);
PointTime time = (PointTime)ra.getTime();
long l = st.getRequestBytesPerLatLonBoxAndTime(latSpan, lonSpan, time.getInterval());
return l;
} else {
throw new IllegalStateException(
"Couldn't calculate the retrieval size for a retrieval of type "

View file

@ -74,6 +74,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
* MAR 27, 2013 1746 dhladky MADIS data record creation
* May 15, 2013 1658 djohnson Add sequence.
* May 16, 2013 753 dhladky Restored dataUri as unique key
* June 03, 2013 1763 dhladky Added ValMap lookups for QCD
* </pre>
*
* @author dhladky
@ -644,6 +645,8 @@ public class MadisRecord extends PersistablePluginDataObject implements
private static final Map<String,QCD> qcdMap;
private static final Map<String, QCD> valMap;
static {
Map<String, QCD> map = new HashMap<String, QCD>();
map.put(V, QCD.VERIFIED);
@ -655,6 +658,17 @@ public class MadisRecord extends PersistablePluginDataObject implements
map.put(Z, QCD.MISSING);
map.put(X, QCD.REJECTED);
qcdMap = Collections.unmodifiableMap(map);
Map<String, QCD> map2 = new HashMap<String, QCD>();
map2.put(QCD.VERIFIED.name(), QCD.VERIFIED);
map2.put(QCD.SCREENDED.name(), QCD.SCREENDED);
map2.put(QCD.QUESTIONED.name(), QCD.QUESTIONED);
map2.put(QCD.COARSEPASS.name(), QCD.COARSEPASS);
map2.put(QCD.BAD.name(), QCD.BAD);
map2.put(QCD.GOOD.name(), QCD.GOOD);
map2.put(QCD.MISSING.name(), QCD.MISSING);
map2.put(QCD.REJECTED.name(), QCD.REJECTED);
valMap = Collections.unmodifiableMap(map2);
}
private final String qcd;
@ -671,6 +685,10 @@ public class MadisRecord extends PersistablePluginDataObject implements
public static QCD fromString(String val) {
return qcdMap.get(val);
}
public static QCD fromVal(String val) {
return valMap.get(val);
}
}

View file

@ -6,6 +6,8 @@
</dateConfig>
<constant name="BLANK" value=""/>
<constant name="SPACE" value=" "/>
<constant name="PLUS" value="+"/>
<constant name="UNKNOWN" value="unknown"/>
<constant name="NONE" value="NONE"/>
<constant name="REQUEST_HEADER" value="request"/>
@ -29,5 +31,9 @@
<constant name="PORT_HEADER" value="http://"/>
<constant name="PORT" value="80"/>
<constant name="COMMA" value=","/>
<constant name="EQUALS" value="="/>
<constant name="OUTPUTFORMAT" value="text/xml"/>
<constant name="FORWARD_SLASH" value="/"/>
<constant name="DEFAULT_CRS" value="crs:84"/>
</serviceConfig>

View file

@ -9,6 +9,9 @@
<!-- for OGC it's your FQDN
!!!!!PLACE YOUR URL HERE!!!!!!-->
<url>http://your.url.here:8085</url>
<userName>user</userName>
<password>password</password>
<encryption>CLEAR</encryption>
</connection>
<providerType dataType="POINT" plugin="madis" availabilityDelay="0" />
<projection type="LatLon">

View file

@ -15,11 +15,9 @@ Require-Bundle: com.raytheon.uf.common.datadelivery.retrieval;bundle-version="1.
com.google.guava;bundle-version="1.0.0",
com.raytheon.uf.common.registry.ebxml;bundle-version="1.0.0",
org.geotools;bundle-version="2.6.4",
com.raytheon.uf.edex.plugin.madis.ogc;bundle-version="1.0.0",
com.raytheon.uf.common.dataplugin.madis;bundle-version="1.0.0",
com.raytheon.uf.common.util;bundle-version="1.12.1174",
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174",
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174",
com.raytheon.uf.common.event;bundle-version="1.0.0",
com.raytheon.uf.edex.ogc.common;bundle-version="1.0.0",
com.raytheon.uf.edex.wfs;bundle-version="1.0.0"
com.raytheon.uf.edex.ogc.common;bundle-version="1.0.0"
Export-Package: com.raytheon.uf.edex.datadelivery.retrieval.wfs

View file

@ -2,11 +2,6 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean factory-bean="metadataAdapterRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.dataplugin.madis.MadisRecord" />
<constructor-arg value="com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters.madis.MadisMetadataAdapter" type="java.lang.Class" />
</bean>
<bean factory-bean="serviceFactoryRegistry" factory-method="register">
<constructor-arg value="WFS" />
<constructor-arg value="com.raytheon.uf.edex.datadelivery.retrieval.wfs.WfsServiceFactory" type="java.lang.Class" />

View file

@ -1,52 +0,0 @@
package com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters.madis;
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.datadelivery.retrieval.metadata.adapters.AbstractMetadataAdapter;
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
* May 31, 2013 2038 djohnson Move to correct git repo.
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class MadisMetadataAdapter extends AbstractMetadataAdapter<Madis> {
public MadisMetadataAdapter() {
}
@Override
public PluginDataObject getRecord(Madis madis) {
return madis.getRecord();
}
@Override
public void allocatePdoArray(int size) {
pdos = new MadisRecord[size];
}
/**
* {@inheritDoc}
*/
@Override
public void processAttributeXml(RetrievalAttribute attXML)
throws InstantiationException {
this.attXML = attXML;
}
}

View file

@ -4,7 +4,8 @@ import javax.xml.bind.JAXBException;
import net.opengis.wfs.v_1_1_0.FeatureCollectionType;
import com.raytheon.uf.edex.ogc.common.jaxb.OgcJaxbManager;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.PluginException;
/**
*
@ -17,6 +18,7 @@ import com.raytheon.uf.edex.ogc.common.jaxb.OgcJaxbManager;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 22, 2013 753 dhladky Initial javadoc
* June 11, 2013 1763 dhladky Moved and updated.
*
* </pre>
*
@ -25,11 +27,9 @@ import com.raytheon.uf.edex.ogc.common.jaxb.OgcJaxbManager;
*/
public interface IWfsMetaDataAdapter {
public void configureMarshaller() throws JAXBException;
public OgcJaxbManager getMarshaller();
public FeatureCollectionType getFeatureCollection(String payload) throws JAXBException;
public PluginDataObject[] setPointData(PluginDataObject[] pdos) throws PluginException;
}

View file

@ -2,10 +2,12 @@ package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.geotools.geometry.jts.ReferencedEnvelope;
import com.raytheon.uf.common.datadelivery.registry.Coverage;
import com.raytheon.uf.common.datadelivery.registry.EnvelopeUtils;
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;
@ -14,6 +16,7 @@ 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;
import com.vividsolutions.jts.geom.Coordinate;
/**
*
@ -27,6 +30,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.request.RequestBuilder;
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky created.
* May 31, 2013 2038 djohnson Move to correct repo.
* Jun 11, 2013 1763 dhladky Made operational.
*
* </pre>
*
@ -43,21 +47,33 @@ public class WfsRequestBuilder extends RequestBuilder {
public static final String separator = getServiceConfig().getConstantValue("COMMA");
public static final String slash = getServiceConfig().getConstantValue("FORWARD_SLASH");
public static final String bbox = getServiceConfig().getConstantValue("BBOX_HEADER");
public static final String srs = getServiceConfig().getConstantValue("SRSNAME_HEADER");
public static final String crs = getServiceConfig().getConstantValue("DEFAULT_CRS");
public static final String time = getServiceConfig().getConstantValue("TIME_HEADER");
public static final String equals = getServiceConfig().getConstantValue("EQUALS");
public static final String blank = getServiceConfig().getConstantValue("BLANK");
public static final String ampersand = "&";
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
@ -73,23 +89,28 @@ public class WfsRequestBuilder extends RequestBuilder {
SimpleDateFormat sdf = new SimpleDateFormat(getServiceConfig()
.getDateConfig().getFormats().get(0));
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
return sdf;
}
};
@Override
public String processTime(Time time) {
public String processTime(Time inTime) {
try {
if (time.getEndDate() != null && time.getStartDate() != null) {
Date sDate = time.getStartDate();
Date eDate = time.getEndDate();
if (inTime.getEndDate() != null && inTime.getStartDate() != null) {
Date sDate = inTime.getStartDate();
Date eDate = inTime.getEndDate();
String endDateString = ogcDateFormat.get().format(eDate);
String startDateString = ogcDateFormat.get().format(sDate);
StringBuilder sb = new StringBuilder();
sb.append("&TIME=");
sb.append(ampersand);
sb.append(time);
sb.append(equals);
sb.append(startDateString);
sb.append("/");
sb.append(slash);
if (!endDateString.equals(startDateString)) {
sb.append(endDateString);
@ -102,31 +123,37 @@ public class WfsRequestBuilder extends RequestBuilder {
}
// no times, return blank
return getServiceConfig().getConstantValue("BLANK");
return 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();
Coordinate ll = EnvelopeUtils.getLowerLeftLatLon(re);
Coordinate ur = EnvelopeUtils.getUpperRightLatLon(re);
// manage the box
double lowerLon = re.getMinX();
double lowerLat = re.getMinY();
double upperLon = re.getMaxX();
double upperLat = re.getMaxY();
double lowerLon = ll.x;
double lowerLat = ll.y;
double upperLon = ur.x;
double upperLat = ur.y;
sb.append("&srsName=");
sb.append(coverage.getEnvelope().getCoordinateReferenceSystem()
.getName());
sb.append("&bbox=");
sb.append(ampersand);
sb.append(srs);
sb.append(equals);
sb.append(crs);
//TODO Revisit this when we have a better idea of how to switch them
//sb.append(coverage.getEnvelope().getCoordinateReferenceSystem()
// .getName());
sb.append(ampersand);
sb.append(bbox);
sb.append(equals);
sb.append(lowerLon);
sb.append(separator);
sb.append(lowerLat);
@ -138,7 +165,7 @@ public class WfsRequestBuilder extends RequestBuilder {
return sb.toString();
}
return getServiceConfig().getConstantValue("BLANK");
return blank;
}
@Override
@ -164,5 +191,5 @@ public class WfsRequestBuilder extends RequestBuilder {
return wfsServiceConfig;
}
}

View file

@ -22,8 +22,8 @@ package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import com.raytheon.uf.common.datadelivery.registry.Provider;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.event.EventBus;
@ -50,6 +50,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.util.WfsConnectionUtil;
* Jul 25, 2012 955 djohnson Moved to wfs specific package.
* May 12, 2013 753 dhladky implemented.
* May 31, 2013 2038 djohnson Move to correct repo.
* Jun 03, 2013 1763 dhladky Readied for retrievals.
*
* </pre>
*
@ -61,8 +62,12 @@ public class WfsRetrievalAdapter extends RetrievalAdapter {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsRetrievalAdapter.class);
private static final Pattern splitter = Pattern.compile("?");
private Provider provider;
WfsRetrievalAdapter(Provider provider) {
this.provider = provider;
}
@Override
public IRetrievalRequestBuilder createRequestMessage(
@ -113,9 +118,7 @@ public class WfsRetrievalAdapter extends RetrievalAdapter {
String xmlMessage = null;
try {
// break url into CGI parameters and address
String[] parts = splitter.split(request.getRequest());
xmlMessage = WfsConnectionUtil.wfsConnect(parts[0], parts[1]);
xmlMessage = WfsConnectionUtil.wfsConnect(request.getRequest(), provider);
} catch (Exception e) {
statusHandler.handle(Priority.ERROR, e.getLocalizedMessage(), e);
EventBus.publish(new RetrievalEvent(e.getMessage()));

View file

@ -11,6 +11,7 @@ import com.raytheon.uf.common.datadelivery.registry.DataType;
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;
import com.raytheon.uf.common.datadelivery.registry.Provider.ServiceType;
import com.raytheon.uf.common.datadelivery.registry.ProviderType;
import com.raytheon.uf.common.datadelivery.registry.Subscription;
@ -39,6 +40,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.adapters.RetrievalAdapter;
* Nov 19, 2012 1166 djohnson Clean up JAXB representation of registry objects.
* May 12, 2013 753 dhladky Implemented
* May 31, 2013 2038 djohnson Move to correct repo.
* Jun 04, 2013 1763 dhladky Readied for WFS Retrievals.
*
* </pre>
*
@ -49,9 +51,11 @@ class WfsRetrievalGenerator extends RetrievalGenerator {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsRetrievalGenerator.class);
private Provider provider;
WfsRetrievalGenerator() {
WfsRetrievalGenerator(Provider provider) {
super(ServiceType.WFS);
this.provider = provider;
}
@Override
@ -82,8 +86,6 @@ class WfsRetrievalGenerator extends RetrievalGenerator {
List<Retrieval> retrievals = new ArrayList<Retrieval>();
Subscription sub = bundle.getSubscription();
sub = removeDuplicates(sub);
if (sub != null) {
PointTime subTime = (PointTime) sub.getTime();
@ -97,7 +99,12 @@ class WfsRetrievalGenerator extends RetrievalGenerator {
}
// with point data they all have the same data
Parameter param = sub.getParameter().get(0);
Parameter param = null;
if (sub.getParameter() != null) {
param = sub.getParameter().get(0);
}
Retrieval retrieval = getRetrieval(sub, bundle, param, subTime);
retrievals.add(retrieval);
}
@ -153,9 +160,7 @@ class WfsRetrievalGenerator extends RetrievalGenerator {
if (dsmd instanceof PointDataSetMetaData) {
// PointDataSetMetaData data = (PointDataSetMetaData) dsmd;
// TODO determine some check for validity of point data sets
return true;
}
return false;
@ -185,11 +190,12 @@ class WfsRetrievalGenerator extends RetrievalGenerator {
// Coverage and type processing
Coverage cov = sub.getCoverage();
if (cov instanceof Coverage) {
retrieval.setDataType(DataType.POINT);
} else {
throw new UnsupportedOperationException(
"WFS retrieval does not yet support coverages other than Point. ");
"WFS retrieval does not support coverages/types other than Point. ");
}
final ProviderType providerType = bundle.getProvider().getProviderType(
@ -198,11 +204,16 @@ class WfsRetrievalGenerator extends RetrievalGenerator {
// Attribute processing
RetrievalAttribute att = new RetrievalAttribute();
Parameter lparam = processParameter(param);
att.setCoverage(cov);
lparam.setLevels(param.getLevels());
if (param != null) {
Parameter lparam = processParameter(param);
lparam.setLevels(param.getLevels());
att.setParameter(lparam);
}
att.setTime(time);
att.setParameter(lparam);
att.setSubName(retrieval.getSubscriptionName());
att.setPlugin(plugin);
att.setProvider(sub.getProvider());
@ -216,12 +227,12 @@ class WfsRetrievalGenerator extends RetrievalGenerator {
*/
@Override
protected RetrievalAdapter getServiceRetrievalAdapter() {
return new WfsRetrievalAdapter();
return new WfsRetrievalAdapter(provider);
}
@Override
protected Subscription removeDuplicates(Subscription sub) {
throw new UnsupportedOperationException("Not implemented");
throw new UnsupportedOperationException("Not implemented for WFS");
}
}

View file

@ -39,6 +39,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.ServiceFactory;
* Jul 25, 2012 955 djohnson Initial creation
* May 12, 2013 753 dhladky implementation
* May 31, 2013 2038 djohnson Add setProvider.
* Jun 11, 2013 1763 dhladky Service provider impl for WFS
*
* </pre>
*
@ -47,6 +48,8 @@ import com.raytheon.uf.edex.datadelivery.retrieval.ServiceFactory;
*/
public class WfsServiceFactory implements ServiceFactory {
private Provider provider;
/*
* (non-Javadoc)
*
@ -78,7 +81,7 @@ public class WfsServiceFactory implements ServiceFactory {
*/
@Override
public RetrievalGenerator getRetrievalGenerator() {
return new WfsRetrievalGenerator();
return new WfsRetrievalGenerator(provider);
}
/**
@ -86,6 +89,6 @@ public class WfsServiceFactory implements ServiceFactory {
*/
@Override
public void setProvider(Provider provider) {
throw new UnsupportedOperationException("Not implemented");
this.provider = provider;
}
}

View file

@ -1,11 +1,7 @@
package com.raytheon.uf.edex.datadelivery.retrieval.wfs;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import net.opengis.gml.v_3_1_1.AbstractFeatureType;
@ -14,16 +10,12 @@ 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.dataplugin.madis.MadisRecord;
import com.raytheon.uf.common.dataplugin.PluginException;
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;
import com.raytheon.uf.edex.datadelivery.retrieval.response.RetrievalTranslator;
import com.raytheon.uf.edex.ogc.common.jaxb.OgcJaxbManager;
import com.raytheon.uf.edex.plugin.madis.ogc.feature.Madis;
import com.raytheon.uf.edex.plugin.madis.ogc.feature.MadisObjectFactory;
import com.raytheon.uf.edex.wfs.reg.Unique;
/**
*
@ -37,7 +29,7 @@ import com.raytheon.uf.edex.wfs.reg.Unique;
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky Initial javadoc
* May 31, 2013 2038 djohnson Move to correct repo.
* May 31, 2013 1763 dhladky Fixed up merge.
* May 31, 2013 1763 dhladky Fixed up merge, made operational.
*
* </pre>
*
@ -83,70 +75,34 @@ public class WfsTranslator extends RetrievalTranslator {
* @param payload
* @return
*/
@SuppressWarnings("unchecked")
public PluginDataObject[] asPluginDataObjects(String payload) {
try {
FeatureCollectionType featureCollection = ((IWfsMetaDataAdapter)metadataAdapter).getFeatureCollection(payload);
IWfsMetaDataAdapter wfsAdapter = (IWfsMetaDataAdapter)metadataAdapter;
FeatureCollectionType featureCollection = wfsAdapter.getFeatureCollection(payload);
if (featureCollection.getNumberOfFeatures().intValue() > 0) {
int i = 0;
metadataAdapter.allocatePdoArray(featureCollection.getNumberOfFeatures().intValue());
for (FeaturePropertyType type : featureCollection.getFeatureMember()) {
JAXBElement<? extends AbstractFeatureType> feature = type.getFeature();
AbstractFeatureType feature = type.getFeature().getValue();
metadataAdapter.getPdos()[i] = metadataAdapter.getRecord(feature);
i++;
}
}
if (metadataAdapter.isPointData()) {
wfsAdapter.setPointData(metadataAdapter.getPdos());
}
} catch (JAXBException e) {
statusHandler.handle(Priority.PROBLEM, "Can't de-serialize FeatureCollection", e);
} catch (PluginException e) {
statusHandler.handle(Priority.PROBLEM, "Can't create plugins.", e);
}
return metadataAdapter.getPdos();
}
public static void main(String[] args) {
String fileName = args[0];
OgcJaxbManager ctx = null;
Class<?>[] classes = new Class<?>[] {
net.opengis.gml.v_3_1_1.ObjectFactory.class,
net.opengis.wfs.v_1_1_0.ObjectFactory.class,
net.opengis.filter.v_1_1_0.ObjectFactory.class,
Unique.class,
Madis.class,
MadisObjectFactory.class};
try {
ctx = new OgcJaxbManager(classes);
} catch (JAXBException e1) {
e1.printStackTrace();
statusHandler.handle(Priority.PROBLEM, e1.getLocalizedMessage(), e1);
}
try {
try {
File file = new File(fileName);
FileReader reader = new FileReader(file);
List<MadisRecord> featureList = new ArrayList<MadisRecord>();
FeatureCollectionType features = (FeatureCollectionType) ctx.unmarshal(reader);
for (FeaturePropertyType type: features.getFeatureMember()) {
Madis feature = (Madis)type.getFeature().getValue();
MadisRecord record = feature.getRecord();
featureList.add(record);
}
System.out.println("FeatureList size: "+featureList.size());
} catch (JAXBException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
}
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
}
}
}

View file

@ -32,7 +32,8 @@ 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",
org.apache.http;bundle-version="4.1.2"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: com.raytheon.uf.edex.datadelivery.retrieval;

View file

@ -0,0 +1,12 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<!-- This should be moved to a grid OGC plugin when one exists -->
<bean factory-bean="metadataAdapterRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.dataplugin.grid.GridRecord" />
<constructor-arg value="com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters.GridMetadataAdapter" type="java.lang.Class" />
</bean>
</beans>

View file

@ -23,11 +23,6 @@
class="com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters.AbstractMetadataAdapter"
factory-method="getMetadataAdapterRegistry" />
<bean factory-bean="metadataAdapterRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.dataplugin.grid.GridRecord" />
<constructor-arg value="com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters.GridMetadataAdapter" type="java.lang.Class" />
</bean>
<!-- Register service factories -->
<bean factory-bean="serviceFactoryRegistry" factory-method="register">
<constructor-arg value="OPENDAP" />

View file

@ -45,6 +45,7 @@ import com.raytheon.uf.common.util.registry.RegistryException;
* Nov 19, 2012 bsteffen Initial javadoc
* May 12, 2013 753 dhladky Added support for Madis
* May 31, 2013 2038 djohnson Plugin contributable registry.
* Jun 11, 2013 2101 dhladky Updated for Madis
*
* </pre>
*
@ -56,6 +57,8 @@ public abstract class AbstractMetadataAdapter<RecordKey> implements
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(AbstractMetadataAdapter.class);
protected boolean isPointData = false;
protected PluginDataObject[] pdos;
@ -139,4 +142,16 @@ public abstract class AbstractMetadataAdapter<RecordKey> implements
public static GenericRegistry<String, Class<AbstractMetadataAdapter<?>>> getMetadataAdapterRegistry() {
return metadataAdapterRegistry;
}
/**
* Sets whether this adapter is pointData or not
* @param isPointData
*/
public void setIsPointData(boolean isPointData) {
this.isPointData = isPointData;
}
public boolean isPointData() {
return isPointData;
}
}

View file

@ -20,7 +20,6 @@ package com.raytheon.uf.edex.datadelivery.retrieval.response;
* further licensing information.
**/
import java.util.ArrayList;
import java.util.List;
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
@ -42,6 +41,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters.AbstractMet
* Feb 07, 2013 1543 djohnson Allow overriding of methods for mocking in tests.
* Feb 12, 2013 1543 djohnson Pass the exception as the cause for instantiation exceptions.
* May 31, 2013 2038 djohnson Protected access for constructor.
* Jun 11, 2013 2101 dhladky Imports
*
* </pre>
*

View file

@ -22,7 +22,6 @@ 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;

View file

@ -88,7 +88,7 @@ public final class RetrievalPersistUtil {
* @param pdos
* @return
*/
public static synchronized boolean routePlugin(String defaultPeristRoute,
public static synchronized boolean routePlugin(String defaultPersistRoute,
String pluginName,
PluginDataObject[] pdos) {
@ -120,7 +120,7 @@ public final class RetrievalPersistUtil {
pluginDao.persistToDatabase(pdos);
EDEXUtil.getMessageProducer().sendAsyncUri(
defaultPeristRoute,
defaultPersistRoute,
pdos);
success = true;
}

View file

@ -1,6 +1,13 @@
package com.raytheon.uf.edex.datadelivery.retrieval.util;
import java.net.URI;
import org.apache.http.client.methods.HttpGet;
import com.raytheon.uf.common.comm.HttpClient;
import com.raytheon.uf.common.comm.HttpClient.HttpClientResponse;
import com.raytheon.uf.common.datadelivery.registry.Connection;
import com.raytheon.uf.common.datadelivery.registry.Provider;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -16,6 +23,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky created.
* May 31, 2013 1763 dhladky refined.
*
* </pre>
*
@ -23,24 +31,41 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
* @version 1.0
*/
public class WfsConnectionUtil {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsConnectionUtil.class);
public static String wfsConnect(String address, String message) {
.getHandler(WfsConnectionUtil.class);
public static String wfsConnect(String url, Provider provider) {
String xmlResponse = null;
// sets up any proxy info that might be necessary
ConnectionUtil.getProxyParameters();
HttpClient http = HttpClient.getInstance();
HttpClient http = null;
try {
xmlResponse = http.post(address, message);
// Sets up any proxy info that might be necessary
// TODO: consider using HTTP POST instead of GET
ConnectionUtil.getProxyParameters();
http = HttpClient.getInstance();
HttpGet get = new HttpGet();
URI uri = new URI(url);
Connection conn = provider.getConnection();
// check for the need to do a username password auth check
if (conn != null && conn.getUserName() != null
&& conn.getPassword() != null) {
http.setCredentials(uri.getHost(), uri.getPort(),
provider.getName(), conn.getUserName(),
conn.getPassword());
}
get.setURI(uri);
HttpClientResponse response = http.executeRequest(get);
xmlResponse = new String(response.data);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, "Couldn't connect to WFS server: "+address+" with posted message of: "+message, e);
statusHandler.handle(Priority.PROBLEM,
"Couldn't connect to WFS server: " + url, e);
}
return xmlResponse;
}

View file

@ -25,6 +25,10 @@ Require-Bundle: com.raytheon.uf.edex.ogc.common;bundle-version="1.0.0",
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174",
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174",
com.raytheon.uf.edex.wms;bundle-version="1.0.0",
com.raytheon.uf.common.time;bundle-version="1.12.1174"
com.raytheon.uf.common.time;bundle-version="1.12.1174",
com.raytheon.uf.edex.datadelivery.retrieval.wfs;bundle-version="1.0.0",
com.raytheon.uf.edex.datadelivery.retrieval;bundle-version="1.0.0",
com.raytheon.uf.common.datadelivery.retrieval;bundle-version="1.0.0"
Export-Package: com.raytheon.uf.edex.plugin.madis.ogc,
com.raytheon.uf.edex.plugin.madis.ogc.feature
com.raytheon.uf.edex.plugin.madis.ogc.feature,
com.raytheon.uf.edex.plugin.madis.ogc.metadata

View file

@ -0,0 +1,9 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean factory-bean="metadataAdapterRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.dataplugin.madis.MadisRecord" />
<constructor-arg value="com.raytheon.uf.edex.plugin.madis.ogc.metadata.MadisMetadataAdapter" type="java.lang.Class" />
</bean>
</beans>

View file

@ -24,6 +24,7 @@ import com.raytheon.uf.edex.wfs.reg.WfsTranslator;
* ------------ ---------- ----------- --------------------------
* 04/01/2013 1746 dhladky Initial creation
* 05/30/2013 753 dhladky updated
* June 03, 2013 1763 dhladky Bulked the PointDataQuery
* </pre>
*
* @author dhladky
@ -42,8 +43,10 @@ public class MadisTranslator implements WfsTranslator {
ArrayList<JAXBElement<? extends AbstractFeatureType>> rval = new ArrayList<JAXBElement<? extends AbstractFeatureType>>(
pdos.length);
MadisPointDataTransform.populatePointDataFields(pdos);
for (PluginDataObject pdo : pdos) {
rval.add(translate(pdo));
rval.add(translate(pdo));
}
return rval;
}
@ -53,11 +56,8 @@ public class MadisTranslator implements WfsTranslator {
* @return
*/
public JAXBElement<Madis> translate(PluginDataObject pdo) {
MadisRecord record = null;
record = MadisPointDataTransform.populatePointDataFields((MadisRecord) pdo);
return new MadisObjectFactory().create(new Madis(record));
return new MadisObjectFactory().create(new Madis((MadisRecord)pdo));
}
}

View file

@ -52,6 +52,7 @@ import com.raytheon.uf.edex.ogc.common.feature.ObsLocation;
* Date Ticket# Engineer Description
* ----------- ---------- ----------- --------------------------
* 3/27/13 1746 dhladky Initial creation
* Jun 03, 2013 1763 dhladky Altered QCD values map
* </pre>
*
* @author dhladky
@ -245,43 +246,43 @@ public class Madis extends AbstractFeatureType {
record.setTimeObs(date);
record.setLocation(getSfcObsLocation(this.getObsLocation()));
record.setDewpoint(this.getDewpoint());
record.setDewpoint_qcd(QCD.fromString(this.getDewpoint_qcd()));
record.setDewpoint_qcd(QCD.fromVal(this.getDewpoint_qcd()));
record.setDewpoint_qca(this.getDewpoint_qca());
record.setDewpoint_qcr(this.getDewpoint_qcr());
record.setRh(this.getRh());
record.setRh_qcd(QCD.fromString(this.getRh_qcd()));
record.setRh_qcd(QCD.fromVal(this.getRh_qcd()));
record.setRh_qca(this.getRh_qca());
record.setRh_qcr(this.getRh_qcr());
record.setAltimeter(this.getAltimeter());
record.setAltimeter_qcd(QCD.fromString(this.getAltimeter_qcd()));
record.setAltimeter_qcd(QCD.fromVal(this.getAltimeter_qcd()));
record.setAltimeter_qca(this.getAltimeter_qca());
record.setAltimeter_qcr(this.getAltimeter_qcr());
record.setTemperature(this.getTemperature());
record.setTemperature_qcd(QCD.fromString(this.getTemperature_qcd()));
record.setTemperature_qcd(QCD.fromVal(this.getTemperature_qcd()));
record.setTemperature_qca(this.getTemperature_qca());
record.setTemperature_qcr(this.getTemperature_qcr());
record.setWindDirection(this.getWindDirection());
record.setWindDirection_qcd(QCD.fromString(this.getWindDirection_qcd()));
record.setWindDirection_qcd(QCD.fromVal(this.getWindDirection_qcd()));
record.setWindDirection_qca(this.getWindDirection_qca());
record.setWindDirection_qcr(this.getWindDirection_qcr());
record.setPrecipRate(this.getPrecipRate());
record.setPrecipRate_qcd(QCD.fromString(this.getPrecipRate_qcd()));
record.setPrecipRate_qcd(QCD.fromVal(this.getPrecipRate_qcd()));
record.setPrecipRate_qca(this.getPrecipRate_qca());
record.setPrecipRate_qcr(this.getPrecipRate_qcr());
record.setWindSpeed(this.getWindSpeed());
record.setWindSpeed_qcd(QCD.fromString(this.getWindSpeed_qcd()));
record.setWindSpeed_qcd(QCD.fromVal(this.getWindSpeed_qcd()));
record.setWindSpeed_qca(this.getWindSpeed_qca());
record.setWindSpeed_qcr(this.getWindSpeed_qcr());
record.setWindGust(this.getWindGust());
record.setWindGust_qcd(QCD.fromString(this.getWindGust_qcd()));
record.setWindGust_qcd(QCD.fromVal(this.getWindGust_qcd()));
record.setWindGust_qca(this.getWindGust_qca());
record.setWindGust_qcr(this.getWindGust_qcr());
record.setPrecipitalWater(this.getPrecipitalWater());
record.setPrecipitalWater_qcd(QCD.fromString(this.getPrecipitalWater_qcd()));
record.setPrecipitalWater_qcd(QCD.fromVal(this.getPrecipitalWater_qcd()));
record.setPrecipitalWater_qca(this.getPrecipitalWater_qca());
record.setPrecipitalWater_qcr(this.getPrecipitalWater_qcr());
record.setPressure(this.getPressure());
record.setPressure_qcd(QCD.fromString(this.getPressure_qcd()));
record.setPressure_qcd(QCD.fromVal(this.getPressure_qcd()));
record.setPressure_qca(this.getPressure_qca());
record.setPressure_qcr(this.getPressure_qcr());

View file

@ -0,0 +1,116 @@
package com.raytheon.uf.edex.plugin.madis.ogc.metadata;
import javax.xml.bind.JAXBException;
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.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.madis.MadisRecord;
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.metadata.adapters.AbstractMetadataAdapter;
import com.raytheon.uf.edex.datadelivery.retrieval.wfs.IWfsMetaDataAdapter;
import com.raytheon.uf.edex.ogc.common.jaxb.OgcJaxbManager;
import com.raytheon.uf.edex.plugin.madis.MadisPointDataTransform;
import com.raytheon.uf.edex.plugin.madis.ogc.feature.Madis;
import com.raytheon.uf.edex.plugin.madis.ogc.feature.MadisObjectFactory;
import com.raytheon.uf.edex.wfs.reg.Unique;
/**
*
* Convert RetrievalAttribute to MadisRecords.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 12, 2013 753 dhladky Initial javadoc
* May 31, 2013 2038 djohnson Move to correct git repo.
* June 03, 2012 1763 dhladky Made operational, moved to ogc plugin
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class MadisMetadataAdapter extends AbstractMetadataAdapter<Madis>
implements IWfsMetaDataAdapter {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(MadisMetadataAdapter.class);
private OgcJaxbManager marshaller = null;
@Override
public PluginDataObject getRecord(Madis madis) {
return madis.getRecord();
}
@Override
public void allocatePdoArray(int size) {
pdos = new MadisRecord[size];
}
/**
* {@inheritDoc}
*/
@Override
public void processAttributeXml(RetrievalAttribute attXML)
throws InstantiationException {
this.attXML = attXML;
}
public void configureMarshaller() throws JAXBException {
if (marshaller == null) {
Class<?>[] classes = new Class<?>[] {
net.opengis.gml.v_3_1_1.ObjectFactory.class,
net.opengis.wfs.v_1_1_0.ObjectFactory.class,
net.opengis.filter.v_1_1_0.ObjectFactory.class,
Unique.class, Madis.class, MadisObjectFactory.class };
try {
marshaller = new OgcJaxbManager(classes);
} catch (JAXBException e1) {
statusHandler.handle(Priority.PROBLEM,
e1.getLocalizedMessage(), e1);
}
}
}
public OgcJaxbManager getMarshaller() {
return marshaller;
}
@Override
public FeatureCollectionType getFeatureCollection(String payload)
throws JAXBException {
// Madis is pointData
setIsPointData(true);
if (marshaller == null) {
configureMarshaller();
}
return (FeatureCollectionType) getMarshaller().unmarshal(payload);
}
/**
* populate pointdata views
* @param pdos
* @return
* @throws PluginException
*/
public PluginDataObject[] setPointData(PluginDataObject[] pdos) throws PluginException {
MadisPointDataTransform mpdt = new MadisPointDataTransform();
mpdt.toPointData(pdos);
return pdos;
}
}

View file

@ -40,14 +40,13 @@ 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.database.DataAccessLayerException;
import com.raytheon.uf.edex.database.plugin.PluginDao;
import com.raytheon.uf.edex.database.query.DatabaseQuery;
import com.raytheon.uf.edex.pointdata.PointDataDbDescription;
import com.raytheon.uf.edex.pointdata.PointDataPluginDao;
import com.raytheon.uf.edex.pointdata.spatial.ObStationDao;
/**
* MadisDao MADIS data DAO
* MadisDao MADIS data DAO
*
* <pre>
*
@ -64,22 +63,22 @@ import com.raytheon.uf.edex.pointdata.spatial.ObStationDao;
*/
public class MadisDao extends PointDataPluginDao<MadisRecord> {
/** The station dao */
private ObStationDao obDao = new ObStationDao();
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(MadisDao.class);
.getHandler(MadisDao.class);
public List<?> queryBySpatialBox(double upperLeftLat, double upperLeftLon,
double lowerRightLat, double lowerRightLon)
throws DataAccessLayerException {
List<ObStation> stationList = obDao.queryBySpatialBox(upperLeftLat,
upperLeftLon, lowerRightLat, lowerRightLon);
List<String> stationNames = new ArrayList<String>();
for (ObStation ob : stationList) {
for (ObStation ob: stationList) {
stationNames.add(ob.getIcao());
}
@ -109,8 +108,8 @@ public class MadisDao extends PointDataPluginDao<MadisRecord> {
*/
public Object[] queryDataUriColumn(final String dataUri) {
String sql = "select datauri from awips.madis where datauri='"
+ dataUri + "';";
String sql = "select datauri from awips.madis where datauri='" + dataUri
+ "';";
Object[] results = executeSQLQuery(sql);
@ -133,8 +132,7 @@ public class MadisDao extends PointDataPluginDao<MadisRecord> {
} catch (JAXBException e) {
statusHandler.error("Unable to load madis Point Data Description",
e);
throw new PluginException(
"Unable to load madis Point Data Description!", e);
throw new PluginException("Unable to load madis Point Data Description!", e);
}
}
@ -144,6 +142,7 @@ public class MadisDao extends PointDataPluginDao<MadisRecord> {
return hdf5DataDescription;
}
public ObStationDao getObDao() {
return obDao;
}
@ -166,7 +165,7 @@ public class MadisDao extends PointDataPluginDao<MadisRecord> {
public MadisRecord newObject() {
return new MadisRecord();
}
/*
* (non-Javadoc)
*

View file

@ -45,6 +45,7 @@ import com.raytheon.uf.edex.pointdata.PointDataQuery;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 28 Mar 2013 1746 dhladky Created
* 10 Jun 2013 1763 dhladky Updates for speed.
* </pre>
*
* @author dhladky
@ -54,91 +55,95 @@ import com.raytheon.uf.edex.pointdata.PointDataQuery;
public class MadisPointDataTransform {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(MadisPointDataTransform.class);
.getHandler(MadisPointDataTransform.class);
public static final String DATASET = "dataset";
public static final String COMMA = ",";
public static final String IN = "in";
public static final String DEWPOINT = "dewpoint";
public static final String DEWPOINT_QCD = "dewpoint_qcd";
public static final String DEWPOINT_QCA = "dewpoint_qca";
public static final String DEWPOINT_QCR = "dewpoint_qcr";
public static final String RH = "rh";
public static final String RH_QCD = "rh_qcd";
public static final String RH_QCA = "rh_qca";
public static final String RH_QCR = "rh_qcr";
public static final String ALTIMETER = "altimeter";
public static final String ALTIMETER_QCD = "altimeter_qcd";
public static final String ALTIMETER_QCA = "altimeter_qca";
public static final String ALTIMETER_QCR = "altimeter_qcr";
public static final String TEMPERATURE = "temperature";
public static final String TEMPERATURE_QCD = "temperature_qcd";
public static final String TEMPERATURE_QCA = "temperature_qca";
public static final String TEMPERATURE_QCR = "temperature_qcr";
public static final String WINDDIRECTION = "windDirection";
public static final String WINDDIRECTION_QCD = "windDirection_qcd";
public static final String WINDDIRECTION_QCA = "windDirection_qca";
public static final String WINDDIRECTION_QCR = "windDirection_qcr";
public static final String PRECIPRATE = "precipRate";
public static final String PRECIPRATE_QCD = "precipRate_qcd";
public static final String PRECIPRATE_QCA = "precipRate_qca";
public static final String PRECIPRATE_QCR = "precipRate_qcr";
public static final String WINDSPEED = "windSpeed";
public static final String WINDSPEED_QCD = "windSpeed_qcd";
public static final String WINDSPEED_QCA = "windSpeed_qca";
public static final String WINDSPEED_QCR = "windSpeed_qcr";
public static final String WINDGUST = "windGust";
public static final String WINDGUST_QCD = "windGust_qcd";
public static final String WINDGUST_QCA = "windGust_qca";
public static final String WINDGUST_QCR = "windGust_qcr";
public static final String PRECIPITALWATER = "precipitalWater";
public static final String PRECIPITALWATER_QCD = "precipitalWater_qcd";
public static final String PRECIPITALWATER_QCA = "precipitalWater_qca";
public static final String PRECIPITALWATER_QCR = "precipitalWater_qcr";
public static final String PRESSURE = "pressure";
public static final String PRESSURE_QCD = "pressure_qcd";
public static final String PRESSURE_QCA = "pressure_qca";
public static final String PRESSURE_QCR = "pressure_qcr";
// -------------- location info ------------------//
// -------------- location info ------------------//
public static final String STATION_NAME = "stationName";
public static final String STATION_ID = "stationId";
@ -148,61 +153,60 @@ public class MadisPointDataTransform {
public static final String LATITUDE = "latitude";
public static final String ELEVATION = "elevation";
// -----------These for actual record ------------//
public static final String PROVIDER = "provider";
public static final String SUB_PROVIDER = "sub_provider";
public static final String RESTRICTION = "restriction";
public static final String TIME_OBS = "timeObs";
public static final String DATA_URI = "dataURI";
public static final String[] ALL_PARAMS = {
DATASET, DEWPOINT, DEWPOINT_QCD, DEWPOINT_QCA, DEWPOINT_QCR, RH, RH_QCD,
RH_QCA, RH_QCR, ALTIMETER, ALTIMETER_QCD, ALTIMETER_QCA,
ALTIMETER_QCR, TEMPERATURE, TEMPERATURE_QCD, TEMPERATURE_QCA,
TEMPERATURE_QCR, WINDDIRECTION, WINDDIRECTION_QCD,
WINDDIRECTION_QCA, WINDDIRECTION_QCR, PRECIPRATE, PRECIPRATE_QCD,
PRECIPRATE_QCA, PRECIPRATE_QCR, WINDSPEED, WINDSPEED_QCD,
WINDSPEED_QCA, WINDSPEED_QCR, WINDGUST, WINDGUST_QCD, WINDGUST_QCA,
WINDGUST_QCR, PRECIPITALWATER, PRECIPITALWATER_QCD,
PRECIPITALWATER_QCA, PRECIPITALWATER_QCR, PRESSURE, PRESSURE_QCD,
PRESSURE_QCA, PRESSURE_QCR };
public static final String[] ALL_PARAMS = { DATASET, DEWPOINT,
DEWPOINT_QCD, DEWPOINT_QCA, DEWPOINT_QCR, RH, RH_QCD, RH_QCA,
RH_QCR, ALTIMETER, ALTIMETER_QCD, ALTIMETER_QCA, ALTIMETER_QCR,
TEMPERATURE, TEMPERATURE_QCD, TEMPERATURE_QCA, TEMPERATURE_QCR,
WINDDIRECTION, WINDDIRECTION_QCD, WINDDIRECTION_QCA,
WINDDIRECTION_QCR, PRECIPRATE, PRECIPRATE_QCD, PRECIPRATE_QCA,
PRECIPRATE_QCR, WINDSPEED, WINDSPEED_QCD, WINDSPEED_QCA,
WINDSPEED_QCR, WINDGUST, WINDGUST_QCD, WINDGUST_QCA, WINDGUST_QCR,
PRECIPITALWATER, PRECIPITALWATER_QCD, PRECIPITALWATER_QCA,
PRECIPITALWATER_QCR, PRESSURE, PRESSURE_QCD, PRESSURE_QCA,
PRESSURE_QCR };
public static final String ALL_PARAMS_LIST;
static {
ALL_PARAMS_LIST = StringUtil.join(ALL_PARAMS, ',');
ALL_PARAMS_LIST = StringUtil.join(ALL_PARAMS, ',');
}
private MadisDao dao;
private PointDataDescription description;
public MadisPointDataTransform() {
try {
this.dao = new MadisDao(MadisRecord.PLUGIN_NAME);
this.description = dao.getPointDataDescription(null);
} catch (Exception e) {
statusHandler.error("Can't create Madis Point data container." + e);
}
public MadisPointDataTransform() throws PluginException {
this.dao = new MadisDao(MadisRecord.PLUGIN_NAME);
this.description = dao.getPointDataDescription(null);
}
/**
* Takes in PDO's puts out populated PointData
*
* @param pdo
* @return
*/
public PluginDataObject[] toPointData(PluginDataObject[] pdos) {
if (pdos != null && pdos.length > 0) {
Map<File, PointDataContainer> pointMap = new HashMap<File, PointDataContainer>();
long time = System.currentTimeMillis();
for (PluginDataObject p : pdos) {
if (!(p instanceof MadisRecord)) {
statusHandler.handle(Priority.WARN,
@ -225,17 +229,18 @@ public class MadisPointDataTransform {
"Can't create pointData container", e);
}
}
long time2 = System.currentTimeMillis();
statusHandler.handle(Priority.INFO,
"MADIS PointData create time: "+(time2-time)+" ms");
statusHandler.handle(Priority.INFO, "MADIS PointData create time: "
+ (time2 - time) + " ms");
}
return pdos;
}
/**
* Builds the PointDataView
*
* @param container
* @param record
* @return
@ -267,7 +272,8 @@ public class MadisPointDataTransform {
pdv.setInt(TEMPERATURE_QCR, record.getTemperature_qcr());
// dew point depression
pdv.setFloat(WINDDIRECTION, record.getWindDirection());
pdv.setString(WINDDIRECTION_QCD, record.getWindDirection_qcd().toString());
pdv.setString(WINDDIRECTION_QCD, record.getWindDirection_qcd()
.toString());
pdv.setInt(WINDDIRECTION_QCA, record.getWindDirection_qca());
pdv.setInt(WINDDIRECTION_QCR, record.getWindDirection_qcr());
// precip rate
@ -287,7 +293,8 @@ public class MadisPointDataTransform {
pdv.setInt(WINDGUST_QCR, record.getWindGust_qcr());
// Precipital Water
pdv.setFloat(PRECIPITALWATER, record.getPrecipitalWater());
pdv.setString(PRECIPITALWATER_QCD, record.getPrecipitalWater_qcd().toString());
pdv.setString(PRECIPITALWATER_QCD, record.getPrecipitalWater_qcd()
.toString());
pdv.setInt(PRECIPITALWATER_QCA, record.getPrecipitalWater_qca());
pdv.setInt(PRECIPITALWATER_QCR, record.getPrecipitalWater_qcr());
// Pressure
@ -295,12 +302,13 @@ public class MadisPointDataTransform {
pdv.setString(PRESSURE_QCD, record.getPressure_qcd().toString());
pdv.setInt(PRESSURE_QCA, record.getPressure_qca());
pdv.setInt(PRESSURE_QCR, record.getPressure_qcr());
return pdv;
}
/**
* Creates a MadisRecord from a PointDataContainer
*
* @param pdc
* @return
*/
@ -338,7 +346,7 @@ public class MadisPointDataTransform {
mr.setPrecipRate_qcd(QCD.fromString(pdv.getString(PRECIPRATE_QCD)));
mr.setPrecipRate_qca(pdv.getInt(PRECIPRATE_QCA));
mr.setPrecipRate_qcr(pdv.getInt(PRECIPRATE_QCR));
// WINDSPEED
// WINDSPEED
mr.setWindSpeed(pdv.getFloat(WINDSPEED));
mr.setWindSpeed_qcd(QCD.fromString(pdv.getString(WINDSPEED_QCD)));
mr.setWindSpeed_qca(pdv.getInt(WINDSPEED_QCA));
@ -350,7 +358,8 @@ public class MadisPointDataTransform {
mr.setWindGust_qcr(pdv.getInt(WINDGUST_QCR));
// Precipital Water
mr.setPrecipitalWater(pdv.getFloat(PRECIPITALWATER));
mr.setPrecipitalWater_qcd(QCD.fromString(pdv.getString(PRECIPITALWATER_QCD)));
mr.setPrecipitalWater_qcd(QCD.fromString(pdv
.getString(PRECIPITALWATER_QCD)));
mr.setPrecipitalWater_qca(pdv.getInt(PRECIPITALWATER_QCA));
mr.setPrecipitalWater_qcr(pdv.getInt(PRECIPITALWATER_QCR));
// Pressure
@ -358,20 +367,18 @@ public class MadisPointDataTransform {
mr.setPressure_qcd(QCD.fromString(pdv.getString(PRESSURE_QCD)));
mr.setPressure_qca(pdv.getInt(PRESSURE_QCA));
mr.setPressure_qcr(pdv.getInt(PRESSURE_QCR));
return mr;
}
/**
* Creates a MadisRecord from a PointDataContainer
*
* @param pdc
* @return
*/
public static MadisRecord toMadisRecord(MadisRecord mr, PointDataContainer container) {
public static MadisRecord toMadisRecord(MadisRecord mr, PointDataView pdv) {
container.setCurrentSz(container.getAllocatedSz());
PointDataView pdv = container.readRandom(0);
mr.setDataset(pdv.getInt(DATASET));
// dewpoint
mr.setDewpoint(pdv.getFloat(DEWPOINT));
@ -403,7 +410,7 @@ public class MadisPointDataTransform {
mr.setPrecipRate_qcd(QCD.fromString(pdv.getString(PRECIPRATE_QCD)));
mr.setPrecipRate_qca(pdv.getInt(PRECIPRATE_QCA));
mr.setPrecipRate_qcr(pdv.getInt(PRECIPRATE_QCR));
// WINDSPEED
// WINDSPEED
mr.setWindSpeed(pdv.getFloat(WINDSPEED));
mr.setWindSpeed_qcd(QCD.fromString(pdv.getString(WINDSPEED_QCD)));
mr.setWindSpeed_qca(pdv.getInt(WINDSPEED_QCA));
@ -415,7 +422,8 @@ public class MadisPointDataTransform {
mr.setWindGust_qcr(pdv.getInt(WINDGUST_QCR));
// Precipital Water
mr.setPrecipitalWater(pdv.getFloat(PRECIPITALWATER));
mr.setPrecipitalWater_qcd(QCD.fromString(pdv.getString(PRECIPITALWATER_QCD)));
mr.setPrecipitalWater_qcd(QCD.fromString(pdv
.getString(PRECIPITALWATER_QCD)));
mr.setPrecipitalWater_qca(pdv.getInt(PRECIPITALWATER_QCA));
mr.setPrecipitalWater_qcr(pdv.getInt(PRECIPITALWATER_QCR));
// Pressure
@ -423,10 +431,10 @@ public class MadisPointDataTransform {
mr.setPressure_qcd(QCD.fromString(pdv.getString(PRESSURE_QCD)));
mr.setPressure_qca(pdv.getInt(PRESSURE_QCA));
mr.setPressure_qcr(pdv.getInt(PRESSURE_QCR));
return mr;
}
/**
* Gets Madis fields out of PointData.
*
@ -438,7 +446,7 @@ public class MadisPointDataTransform {
PointDataQuery request = null;
PointDataContainer result = null;
try {
request = new PointDataQuery(MadisRecord.PLUGIN_NAME);
request.requestAllLevels();
@ -446,13 +454,69 @@ public class MadisPointDataTransform {
request.setParameters(ALL_PARAMS_LIST);
result = request.execute();
if (result != null) {
record = toMadisRecord(record, result);
result.setCurrentSz(result.getAllocatedSz());
PointDataView pdv = result.readRandom(0);
record = toMadisRecord(record, pdv);
}
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
}
return record;
}
/**
* Gets Madis fields out of PointData.
*
* @param madisRecord
* []
* @return populated Madis record Array
* @throws PluginException
*/
// TODO I would like to make a PointDataInterface that could implement this
// and other methods that all of these
// will use.
public static PluginDataObject[] populatePointDataFields(
PluginDataObject[] records) {
PointDataQuery request = null;
PointDataContainer result = null;
StringBuilder uris = new StringBuilder();
for (int i = 0; i < records.length; i++) {
uris.append(records[i].getDataURI());
if (i < records.length - 1) {
uris.append(COMMA);
}
}
try {
// TODO: We wnat to get rid of dataURI so,
// When we do the 2020 integration this summer, replace dataURI and sue this instead.
// RequestConstraint.toConstraintMapping(DataURIUtil.createDataURIMap(uri));
request = new PointDataQuery(MadisRecord.PLUGIN_NAME);
request.requestAllLevels();
request.addParameter(DATA_URI, uris.toString(), IN);
request.setParameters(ALL_PARAMS_LIST);
result = request.execute();
for (int i = 0; i < records.length; i++) {
PointDataView pdv = result.readRandom(i);
toMadisRecord((MadisRecord) records[i], pdv);
}
if (result != null) {
statusHandler.info("Results: " + result.getCurrentSz()
+ " point data views.");
}
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
"Unable to populate point data records!", e);
}
return records;
}
}

View file

@ -172,7 +172,7 @@ public class DigitalMesoCycloneTabularProduct extends RadarProduct {
.getTime()))) {
processAlarms = true;
alarmString = new StringBuffer();
alarmString.append("NEW DMDcirculation for "
alarmString.append("NEW DMD circulation for "
+ filter.icao + " over the last "
+ alarms.getDmdAlarmTime() + " minutes.");
}

View file

@ -27,6 +27,7 @@
* ------------ ---------- ----------- --------------------------
* Apr 22, 2011 bclement Initial creation
* May 30. 2013 753 dhladky updates
* Jun 11, 2013 2101 dhladky More speed improvements
*
*/
package com.raytheon.uf.edex.wfs;
@ -80,59 +81,89 @@ import com.raytheon.uf.edex.wfs.request.WfsRequest.Type;
public class WfsHttpHandler implements OgcHttpHandler {
public final String REQUEST_HEADER;
public final String TIME_HEADER;
protected final String REQUEST_HEADER;
protected final String BLANK;
protected final String CAP_PARAM;
protected final String DESC_PARAM;
protected final String GET_PARAM;
protected final String OUTFORMAT_HEADER;
protected final String RESTYPE_HEADER;
protected final String PROPNAME_HEADER;
protected final String MAXFEAT_HEADER;
protected final String SRSNAME_HEADER;
protected final String TYPENAME_HEADER;
protected final String FEATID_HEADER;
protected final String FILTER_HEADER;
protected final String BBOX_HEADER;
protected final String SORTBY_HEADER;
protected final String NS_HEADER;
protected final String PORT_HEADER;
protected final String TIME_HEADER;
protected final String PLUS;
protected final String SPACE;
protected int PORT;
protected final String WFS;
protected final String VERSION;
protected final String OUTPUTFORMAT;
protected static final Pattern nspattern = Pattern
.compile("xmlns\\((\\S+)=(\\S+)\\)");
protected static final Pattern doubleBackSlash = Pattern.compile("\\\\");
protected static final Pattern slash = Pattern.compile("/");
protected static final String comma = ",";
public final String CAP_PARAM ;
public final String DESC_PARAM;
public final String GET_PARAM;
public final String OUTFORMAT_HEADER;
public final String RESTYPE_HEADER;
public final String PROPNAME_HEADER;
public final String MAXFEAT_HEADER;
public final String SRSNAME_HEADER;
public final String TYPENAME_HEADER;
public final String FEATID_HEADER;
public final String FILTER_HEADER;
public final String BBOX_HEADER;
public final String SORTBY_HEADER;
public final String VERSION;
public final String PORT_HEADER;
public final Integer PORT;
public final String WFS;
public final String NS_HEADER;
protected final Pattern nspattern = Pattern.compile("xmlns\\((\\S+)=(\\S+)\\)");
//TODO make all of these read eventually from the WFSConfig
protected final String slashes = "\\\\,";
protected final String lamdas = "λλλ";
//protected final Pattern parens = Pattern.compile("\\s*\\(", "");
protected final Pattern sortBys = Pattern.compile("\\s+");
protected final Pattern slash = Pattern.compile("\\");
protected final Pattern comma = Pattern.compile(",");
protected static final Pattern commaPattern = Pattern.compile(",");
protected static final String parenMatcher = "\\s*\\(";
protected static final String questionMark = "?";
protected static final String equals = "=";
protected static final String lamdas = "λλλ";
protected static final String escapedComma = "\\\\,";
protected static final Pattern sortBys = Pattern.compile("\\s+");
protected final String COLON = ":";
protected static final Pattern parensPattern = Pattern.compile(parenMatcher);
protected static final Pattern escapedCommaPattern = Pattern.compile(escapedComma);
protected static final Pattern lamdasPattern = Pattern.compile(lamdas);
protected WfsProvider provider;
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(WfsHttpHandler.class);
.getHandler(WfsHttpHandler.class);
protected static ServiceConfig wfsServiceConfig;
@ -149,28 +180,51 @@ public class WfsHttpHandler implements OgcHttpHandler {
};
public WfsHttpHandler(WfsProvider provider) {
REQUEST_HEADER = getServiceConfig().getConstantByName("REQUEST_HEADER").getValue();
TIME_HEADER = getServiceConfig().getConstantByName("TIME_HEADER").getValue();
CAP_PARAM = getServiceConfig().getConstantByName("CAP_PARAM").getValue();
DESC_PARAM = getServiceConfig().getConstantByName("DESC_PARAM").getValue();
GET_PARAM = getServiceConfig().getConstantByName("GET_PARAM").getValue();
OUTFORMAT_HEADER = getServiceConfig().getConstantByName("OUTFORMAT_HEADER").getValue();
RESTYPE_HEADER = getServiceConfig().getConstantByName("RESTYPE_HEADER").getValue();
PROPNAME_HEADER = getServiceConfig().getConstantByName("PROPNAME_HEADER").getValue();
MAXFEAT_HEADER = getServiceConfig().getConstantByName("MAXFEAT_HEADER").getValue();
SRSNAME_HEADER = getServiceConfig().getConstantByName("SRSNAME_HEADER").getValue();
TYPENAME_HEADER = getServiceConfig().getConstantByName("TYPENAME_HEADER").getValue();
FEATID_HEADER = getServiceConfig().getConstantByName("FEATID_HEADER").getValue();
FILTER_HEADER = getServiceConfig().getConstantByName("FILTER_HEADER").getValue();
BBOX_HEADER = getServiceConfig().getConstantByName("BBOX_HEADER").getValue();
SORTBY_HEADER = getServiceConfig().getConstantByName("SORTBY_HEADER").getValue();
REQUEST_HEADER = getServiceConfig().getConstantByName("REQUEST_HEADER")
.getValue();
TIME_HEADER = getServiceConfig().getConstantByName("TIME_HEADER")
.getValue();
CAP_PARAM = getServiceConfig().getConstantByName("CAP_PARAM")
.getValue();
DESC_PARAM = getServiceConfig().getConstantByName("DESC_PARAM")
.getValue();
GET_PARAM = getServiceConfig().getConstantByName("GET_PARAM")
.getValue();
OUTFORMAT_HEADER = getServiceConfig().getConstantByName(
"OUTFORMAT_HEADER").getValue();
RESTYPE_HEADER = getServiceConfig().getConstantByName("RESTYPE_HEADER")
.getValue();
PROPNAME_HEADER = getServiceConfig().getConstantByName(
"PROPNAME_HEADER").getValue();
MAXFEAT_HEADER = getServiceConfig().getConstantByName("MAXFEAT_HEADER")
.getValue();
SRSNAME_HEADER = getServiceConfig().getConstantByName("SRSNAME_HEADER")
.getValue();
TYPENAME_HEADER = getServiceConfig().getConstantByName(
"TYPENAME_HEADER").getValue();
FEATID_HEADER = getServiceConfig().getConstantByName("FEATID_HEADER")
.getValue();
FILTER_HEADER = getServiceConfig().getConstantByName("FILTER_HEADER")
.getValue();
BBOX_HEADER = getServiceConfig().getConstantByName("BBOX_HEADER")
.getValue();
SORTBY_HEADER = getServiceConfig().getConstantByName("SORTBY_HEADER")
.getValue();
VERSION = getServiceConfig().getConstantByName("VERSION").getValue();
PORT_HEADER = getServiceConfig().getConstantByName("PORT_HEADER").getValue();
PORT = Integer.valueOf(getServiceConfig().getConstantByName("PORT").getValue());
PORT_HEADER = getServiceConfig().getConstantByName("PORT_HEADER")
.getValue();
PORT = Integer.valueOf(getServiceConfig().getConstantByName("PORT")
.getValue());
WFS = getServiceConfig().getConstantByName("WFS").getValue();
NS_HEADER = getServiceConfig().getConstantByName("NS_HEADER").getValue();
NS_HEADER = getServiceConfig().getConstantByName("NS_HEADER")
.getValue();
BLANK = getServiceConfig().getConstantByName("BLANK").getValue();
OUTPUTFORMAT = getServiceConfig().getConstantByName("OUTPUTFORMAT")
.getValue();
PLUS = getServiceConfig().getConstantByName("PLUS").getValue();
SPACE = getServiceConfig().getConstantByName("SPACE").getValue();
this.provider = provider;
}
@ -185,8 +239,12 @@ public class WfsHttpHandler implements OgcHttpHandler {
@Override
public void handle(OgcHttpRequest req) {
try {
long time = System.currentTimeMillis();
handleInternal(req);
statusHandler.info(req.getRequest().getRequestURL().toString());
long time2 = System.currentTimeMillis();
statusHandler.info("Processed: "
+ req.getRequest().getQueryString() + " in "
+ (time2 - time) + " ms");
} catch (Exception e) {
statusHandler.error("Unable to handle request", e);
}
@ -217,72 +275,72 @@ public class WfsHttpHandler implements OgcHttpHandler {
switch (request.getType()) {
case DescribeFeature:
rval = provider.describeFeatureType((DescFeatureTypeReq) request,
serviceInfo);
break;
case GetCapabilities:
rval = provider.getCapabilities((GetCapReq) request, serviceInfo);
break;
case GetFeature:
rval = provider.getFeature((GetFeatureReq) request, serviceInfo);
break;
case Transaction:
rval = provider.transaction((TransReq) request);
break;
case ERROR:
rval = (OgcResponse) request.getRawrequest();
break;
}
sendResponse(response, rval);
}
serviceInfo);
break;
case GetCapabilities:
rval = provider.getCapabilities((GetCapReq) request, serviceInfo);
break;
case GetFeature:
rval = provider.getFeature((GetFeatureReq) request, serviceInfo);
break;
case Transaction:
rval = provider.transaction((TransReq) request);
break;
case ERROR:
rval = (OgcResponse) request.getRawrequest();
break;
}
sendResponse(response, rval);
}
/**
* @param request
* @return
*/
private OgcResponse validateExceptionFormat(WfsRequest request) {
if (!request.getExceptionFormat().equalsIgnoreCase(
OgcResponse.TEXT_HTML_MIME)
&& !request.getExceptionFormat().equalsIgnoreCase(
OgcResponse.TEXT_XML_MIME)) {
return provider.getError(new WfsException(
Code.INVALID_PARAMETER_VALUE,
"exceptions parameter invalid"), OgcResponse.TEXT_XML_MIME);
}
return null;
}
/**
* @param request
* @return
*/
private OgcResponse validateExceptionFormat(WfsRequest request) {
if (!request.getExceptionFormat().equalsIgnoreCase(
OgcResponse.TEXT_HTML_MIME)
&& !request.getExceptionFormat().equalsIgnoreCase(
OgcResponse.TEXT_XML_MIME)) {
return provider.getError(new WfsException(
Code.INVALID_PARAMETER_VALUE,
"exceptions parameter invalid"), OgcResponse.TEXT_XML_MIME);
}
return null;
}
protected WfsRequest getRequestFromHeaders(Map<String, Object> headers) {
WfsRequest rval = null;
Object obj = headers.get(REQUEST_HEADER);
if (obj instanceof String) {
String req = (String) obj;
if (req.equalsIgnoreCase(CAP_PARAM)) {
rval = new GetCapReq();
} else if (req.equalsIgnoreCase(DESC_PARAM)) {
rval = buildDescFeatureReq(headers);
} else if (req.equalsIgnoreCase(GET_PARAM)) {
rval = buildGetFeatureReq(headers);
}
}
String exceptionFormat = getHeader(EXCEP_FORMAT_HEADER, headers);
if (exceptionFormat == null || exceptionFormat.isEmpty()) {
exceptionFormat = OgcResponse.TEXT_XML_MIME;
}
if (rval == null) {
OgcResponse error = provider.getError(new WfsException(
Code.INVALID_REQUEST, "Unable to decode request"),
exceptionFormat);
rval = new WfsRequest(Type.ERROR);
rval.setRawrequest(error);
}
protected WfsRequest getRequestFromHeaders(Map<String, Object> headers) {
WfsRequest rval = null;
Object obj = headers.get(REQUEST_HEADER);
if (obj instanceof String) {
String req = (String) obj;
if (req.equalsIgnoreCase(CAP_PARAM)) {
rval = new GetCapReq();
} else if (req.equalsIgnoreCase(DESC_PARAM)) {
rval = buildDescFeatureReq(headers);
} else if (req.equalsIgnoreCase(GET_PARAM)) {
rval = buildGetFeatureReq(headers);
}
}
String exceptionFormat = getHeader(EXCEP_FORMAT_HEADER, headers);
if (exceptionFormat == null || exceptionFormat.isEmpty()) {
exceptionFormat = OgcResponse.TEXT_XML_MIME;
}
if (rval == null) {
OgcResponse error = provider.getError(new WfsException(
Code.INVALID_REQUEST, "Unable to decode request"),
exceptionFormat);
rval = new WfsRequest(Type.ERROR);
rval.setRawrequest(error);
}
return rval;
}
return rval;
}
protected Map<String, String> getNameSpaceMap(Map<String, Object> headers) {
Map<String, String> nsmap = new HashMap<String, String>();
String ns = getHeader(NS_HEADER, headers);
if (ns != null) {
protected Map<String, String> getNameSpaceMap(Map<String, Object> headers) {
Map<String, String> nsmap = new HashMap<String, String>();
String ns = getHeader(NS_HEADER, headers);
if (ns != null) {
for (String s : splitOnComma(ns)) {
Matcher matcher = nspattern.matcher(s);
if (matcher.matches()) {
@ -292,166 +350,173 @@ public class WfsHttpHandler implements OgcHttpHandler {
} else {
nsmap.put(OgcPrefix.EDEX, OgcNamespace.EDEX);
}
return nsmap;
}
return nsmap;
}
protected String[] splitOnComma(String str) {
// TODO Use pattern for replace
String val = str.replaceAll(slashes, lamdas);
String[] rval = comma.split(val);
for (int i = 0; i < rval.length; ++i) {
rval[i] = rval[i].replaceAll(lamdas, comma.pattern());
}
return rval;
}
protected String[] splitOnSlash(String str) {
protected String[] splitOnComma(String str) {
String[] rval = commaPattern.split(escapedCommaPattern.matcher(str).replaceAll(lamdas));
for (int i = 0; i < rval.length; ++i) {
rval[i] = lamdasPattern.matcher(rval[i]).replaceAll(comma);
}
return rval;
}
protected String[] splitOnSlash(String str) {
String[] times = slash.split(str);
return times;
}
/**
* @param headers
* @return
*/
protected GetFeatureReq buildGetFeatureReq(Map<String, Object> headers) {
GetFeatureReq rval = new GetFeatureReq();
String resType = getHeader(RESTYPE_HEADER, headers);
if (resType != null) {
ResultType valueOf = GetFeatureReq.ResultType.valueOf(resType);
if (valueOf != null) {
rval.setResulttype(valueOf);
}
}
String max = getHeader(MAXFEAT_HEADER, headers);
if (max != null) {
try {
rval.setMaxFeatures(Integer.parseInt(max));
} catch (NumberFormatException e) {
// ignore
}
}
String outputformat = getHeader(OUTFORMAT_HEADER, headers);
if (outputformat != null) {
rval.setOutputformat(outputformat);
}
Map<String, String> nsmap = getNameSpaceMap(headers);
String[] bboxes = splitOnParens(BBOX_HEADER, headers);
String[] times = splitOnParens(TIME_HEADER, headers);
String[] filters = splitOnParens(FILTER_HEADER, headers);
String[] sorts = splitOnParens(SORTBY_HEADER, headers);
String[] props = splitOnParens(PROPNAME_HEADER, headers);
String[] srsnames = splitOnParens(SRSNAME_HEADER, headers);
String[] types = getHeaderArr(TYPENAME_HEADER, headers);
for (int i = 0; i < types.length; ++i) {
FeatureQuery fq = new FeatureQuery();
if (bboxes.length > 0) {
fq.setFilter(getBoundingBox(bboxes[i]), QFilterType.BBOX);
} else if (filters.length > 0) {
fq.setFilter(filters[i], QFilterType.XML);
}
fq.setTypeNames(getTypeNames(types[i], nsmap));
if (i < sorts.length) {
fq.setSortBys(getSortBys(sorts[i]));
}
if (i < props.length) {
fq.setPropertyNames(Arrays.asList(splitOnComma(props[i])));
}
if (i < srsnames.length) {
fq.setSrsName(srsnames[i]);
}
if (i < times.length) {
fq.setTimeRange(getTimeRange(times[i]));
}
rval.addQuery(fq);
}
return rval;
}
/**
* @param headers
* @return
*/
protected GetFeatureReq buildGetFeatureReq(Map<String, Object> headers) {
GetFeatureReq rval = new GetFeatureReq();
String resType = getHeader(RESTYPE_HEADER, headers);
if (resType != null) {
ResultType valueOf = GetFeatureReq.ResultType.valueOf(resType);
if (valueOf != null) {
rval.setResulttype(valueOf);
}
}
String max = getHeader(MAXFEAT_HEADER, headers);
if (max != null) {
try {
rval.setMaxFeatures(Integer.parseInt(max));
} catch (NumberFormatException e) {
statusHandler
.warn("Can't read the max number of features in request! "
+ max);
}
}
String outputformat = getHeader(OUTFORMAT_HEADER, headers);
if (outputformat != null) {
rval.setOutputformat(outputformat);
}
Map<String, String> nsmap = getNameSpaceMap(headers);
String[] bboxes = splitOnParens(BBOX_HEADER, headers);
String[] times = splitOnParens(TIME_HEADER, headers);
String[] filters = splitOnParens(FILTER_HEADER, headers);
String[] sorts = splitOnParens(SORTBY_HEADER, headers);
String[] props = splitOnParens(PROPNAME_HEADER, headers);
String[] srsnames = splitOnParens(SRSNAME_HEADER, headers);
String[] types = getHeaderArr(TYPENAME_HEADER, headers);
for (int i = 0; i < types.length; ++i) {
FeatureQuery fq = new FeatureQuery();
if (bboxes.length > 0) {
fq.setFilter(getBoundingBox(bboxes[i]), QFilterType.BBOX);
} else if (filters.length > 0) {
fq.setFilter(filters[i], QFilterType.XML);
}
fq.setTypeNames(getTypeNames(types[i], nsmap));
if (i < sorts.length) {
fq.setSortBys(getSortBys(sorts[i]));
}
if (i < props.length) {
fq.setPropertyNames(Arrays.asList(splitOnComma(props[i])));
}
if (i < srsnames.length) {
fq.setSrsName(srsnames[i]);
}
if (i < times.length) {
fq.setTimeRange(getTimeRange(times[i]));
}
rval.addQuery(fq);
}
return rval;
}
/**
* @param nsmap
* @param string
* @return
*/
protected List<QualifiedName> getTypeNames(String typename,
Map<String, String> nsmap) {
int index = typename.lastIndexOf(":");
String type = typename.substring(index+1);
String namespace = typename.substring(0, index);
List<QualifiedName> rval = new LinkedList<QualifiedName>();
if (index == 0) {
// default names to the edex namespace
rval.add(new QualifiedName(OgcNamespace.EDEX, typename, null));
} else {
rval.add(new QualifiedName(namespace, type, type));
}
return rval;
}
/**
* @param nsmap
* @param string
* @return
*/
protected List<QualifiedName> getTypeNames(String typename,
Map<String, String> nsmap) {
int index = typename.lastIndexOf(":");
String type = typename.substring(index + 1);
String namespace = typename.substring(0, index);
List<QualifiedName> rval = new LinkedList<QualifiedName>();
if (index == 0) {
// default names to the edex namespace
rval.add(new QualifiedName(OgcNamespace.EDEX, typename, null));
} else {
rval.add(new QualifiedName(namespace, type, type));
}
return rval;
}
protected String[] splitOnParens(String name, Map<String, Object> headers) {
String val = getHeader(name, headers);
String[] rval;
// TODO use pattern to do the replace and split
if (val != null) {
val = val.replaceAll("\\s*\\(", "\\");
rval = val.split("\\)");
} else {
rval = new String[0];
}
return rval;
}
protected String[] splitOnParens(String name, Map<String, Object> headers) {
String val = getHeader(name, headers);
String[] rval;
if (val != null) {
rval = doubleBackSlash.split(parensPattern.matcher(val).replaceAll(BLANK));
} else {
rval = new String[0];
}
return rval;
}
/**
* @param headers
* @return
*/
protected List<SortBy> getSortBys(String sortby) {
List<SortBy> rval = new LinkedList<SortBy>();
String[] sorts = splitOnComma(sortby);
for (String s : sorts) {
String[] parts = sortBys.split(s);
SortBy.Order order = Order.Ascending;
if (parts.length == 2) {
if (parts[1].trim().equalsIgnoreCase("D")) {
order = Order.Descending;
}
}
rval.add(new SortBy(parts[0].trim(), order));
}
return rval;
}
/**
* @param headers
* @return
*/
protected List<SortBy> getSortBys(String sortby) {
List<SortBy> rval = new LinkedList<SortBy>();
String[] sorts = splitOnComma(sortby);
for (String s : sorts) {
String[] parts = sortBys.split(s);
SortBy.Order order = Order.Ascending;
if (parts.length == 2) {
if (parts[1].trim().equalsIgnoreCase("D")) {
order = Order.Descending;
}
}
rval.add(new SortBy(parts[0].trim(), order));
}
return rval;
}
/**
* @param bboxes
* @return
*/
protected OgcBoundingBox getBoundingBox(String bbox) {
String[] parts = splitOnComma(bbox);
OgcBoundingBox rval = null;
if (parts.length == 4) {
rval = new OgcBoundingBox();
try {
rval.setMinx(Double.parseDouble(parts[0]));
rval.setMiny(Double.parseDouble(parts[1]));
rval.setMaxx(Double.parseDouble(parts[2]));
rval.setMaxy(Double.parseDouble(parts[3]));
} catch (NumberFormatException e) {
statusHandler.error("couldn't parse Bounding Box!", e);
}
}// else TODO handle non 2d WGS84
return rval;
}
/**
* @param bboxes
* @return
*/
protected OgcBoundingBox getBoundingBox(String bbox) {
String[] parts = splitOnComma(bbox);
OgcBoundingBox rval = null;
if (parts.length == 4) {
rval = new OgcBoundingBox();
try {
rval.setMinx(Double.parseDouble(parts[0]));
rval.setMiny(Double.parseDouble(parts[1]));
rval.setMaxx(Double.parseDouble(parts[2]));
rval.setMaxy(Double.parseDouble(parts[3]));
} catch (NumberFormatException e) {
statusHandler.error("couldn't parse Bounding Box!", e);
}
}// else TODO handle non 2d WGS84
return rval;
}
protected OgcTimeRange getTimeRange(String stimes) {
OgcTimeRange otr = null;
// we assume it is a start time going up to present
try {
String[] times = splitOnSlash(stimes);
String[] intimes = splitOnSlash(stimes);
String[] times = new String[intimes.length];
for (int i = 0; i < intimes.length; i++) {
// TODO figure out why "+" for TimeZone gets hacked out of times
String newtime = intimes[i].replace(SPACE, PLUS);
times[i] = newtime;
}
if (times.length > 0) {
Date endDate = null;
Date startDate = null;
if (times.length == 1) {
endDate = new Date(System.currentTimeMillis());
startDate = ogcDateFormat.get().parse(times[0]);
@ -469,47 +534,46 @@ public class WfsHttpHandler implements OgcHttpHandler {
return otr;
}
/**
* @param headers
* @return
*/
protected DescFeatureTypeReq buildDescFeatureReq(Map<String, Object> headers) {
DescFeatureTypeReq rval = new DescFeatureTypeReq();
String outputformat = getHeader(OUTFORMAT_HEADER, headers);
if (outputformat != null) {
rval.setOutputformat(outputformat);
}
String typename = getHeader(TYPENAME_HEADER, headers);
if (typename != null) {
Map<String, String> nsmap = getNameSpaceMap(headers);
rval.setTypenames(getTypeNames(typename, nsmap));
}
return rval;
}
protected String getHeader(String name, Map<String, Object> headers) {
Object obj = headers.get(name);
String rval = null;
if (obj != null && obj instanceof String) {
rval = (String) obj;
}
return rval;
}
protected String[] getHeaderArr(String name, Map<String, Object> headers) {
String[] rval;
String value = getHeader(name, headers);
if (value != null) {
rval = splitOnComma(value);
} else {
rval = new String[0];
}
return rval;
}
protected String[] getHeaderTimes(String name, Map<String, Object> headers) {
/**
* @param headers
* @return
*/
protected DescFeatureTypeReq buildDescFeatureReq(Map<String, Object> headers) {
DescFeatureTypeReq rval = new DescFeatureTypeReq();
String outputformat = getHeader(OUTFORMAT_HEADER, headers);
if (outputformat != null) {
rval.setOutputformat(outputformat);
}
String typename = getHeader(TYPENAME_HEADER, headers);
if (typename != null) {
Map<String, String> nsmap = getNameSpaceMap(headers);
rval.setTypenames(getTypeNames(typename, nsmap));
}
return rval;
}
protected String getHeader(String name, Map<String, Object> headers) {
Object obj = headers.get(name);
String rval = null;
if (obj != null && obj instanceof String) {
rval = (String) obj;
}
return rval;
}
protected String[] getHeaderArr(String name, Map<String, Object> headers) {
String[] rval;
String value = getHeader(name, headers);
if (value != null) {
rval = splitOnComma(value);
} else {
rval = new String[0];
}
return rval;
}
protected String[] getHeaderTimes(String name, Map<String, Object> headers) {
String[] rval;
String value = getHeader(name, headers);
if (value != null) {
@ -520,62 +584,70 @@ public class WfsHttpHandler implements OgcHttpHandler {
return rval;
}
/**
* @param httpRequest
* @return
*/
protected OgcServiceInfo<WfsOpType> getServiceInfo(
HttpServletRequest request) {
return getServiceInfo(request.getServerName(), request.getServerPort());
}
/**
* @param httpRequest
* @return
*/
protected OgcServiceInfo<WfsOpType> getServiceInfo(
HttpServletRequest request) {
return getServiceInfo(request.getServerName(), request.getServerPort());
}
public OgcServiceInfo<WfsOpType> getServiceInfo(String host, int port) {
String base = PORT_HEADER + host;
if (port != PORT) {
base += ":" + port;
}
base += "/" + WFS;
public OgcServiceInfo<WfsOpType> getServiceInfo(String host, int port) {
String base = PORT_HEADER + host;
if (port != PORT) {
base += COLON + port;
}
base += slash.pattern() + WFS;
OgcServiceInfo<WfsOpType> rval = new OgcServiceInfo<WfsOpType>(base);
String getCapGet = base + "?" + REQUEST_HEADER + "=" + CAP_PARAM;
String getFeatureGet = base + "?" + REQUEST_HEADER + "=" + GET_PARAM;
String descFeatureGet = base + "?" + REQUEST_HEADER + "=" + DESC_PARAM;
rval.addOperationInfo(getOp(getCapGet, base, WfsOpType.GetCapabilities));
rval.addOperationInfo(getOp(descFeatureGet, base,
StringBuilder getCapGet = new StringBuilder();
getCapGet.append(base).append(questionMark).append(REQUEST_HEADER)
.append(equals).append(CAP_PARAM);
StringBuffer getFeatureGet = new StringBuffer();
getFeatureGet.append(base).append(questionMark).append(REQUEST_HEADER)
.append(equals).append(GET_PARAM);
StringBuffer descFeatureGet = new StringBuffer();
descFeatureGet.append(base).append(questionMark).append(REQUEST_HEADER)
.append(equals).append(DESC_PARAM);
rval.addOperationInfo(getOp(getCapGet.toString(), base,
WfsOpType.GetCapabilities));
rval.addOperationInfo(getOp(descFeatureGet.toString(), base,
WfsOpType.DescribeFeatureType));
OgcOperationInfo<WfsOpType> getFeat = getOp(getFeatureGet, base,
WfsOpType.GetFeature);
OgcOperationInfo<WfsOpType> getFeat = getOp(getFeatureGet.toString(),
base, WfsOpType.GetFeature);
getFeat.addFormat(ShpFeatureFormatter.mimeType);
getFeat.addFormat(JsonFeatureFormatter.mimeType);
rval.addOperationInfo(getFeat);
return rval;
}
return rval;
}
protected OgcOperationInfo<WfsOpType> getOp(String get, String post,
WfsOpType type) {
OgcOperationInfo<WfsOpType> rval = new OgcOperationInfo<WfsOpType>(type);
rval.setHttpGetRes(get);
rval.setHttpPostRes(post);
rval.addVersion(VERSION);
rval.addFormat("text/xml");
return rval;
}
protected OgcOperationInfo<WfsOpType> getOp(String get, String post,
WfsOpType type) {
OgcOperationInfo<WfsOpType> rval = new OgcOperationInfo<WfsOpType>(type);
rval.setHttpGetRes(get);
rval.setHttpPostRes(post);
rval.addVersion(VERSION);
rval.addFormat(OUTPUTFORMAT);
return rval;
}
protected void sendResponse(HttpServletResponse httpRes,
OgcResponse response) throws Exception {
OgcResponseOutput.output(response, httpRes);
}
protected void sendResponse(HttpServletResponse httpRes,
OgcResponse response) throws Exception {
OgcResponseOutput.output(response, httpRes);
}
/**
* Get service config
* @return
*/
protected static ServiceConfig getServiceConfig() {
if (wfsServiceConfig == null) {
wfsServiceConfig = HarvesterServiceManager.getInstance()
.getServiceConfig(ServiceType.WFS);
}
return wfsServiceConfig;
}
/**
* Get service config
*
* @return
*/
protected static ServiceConfig getServiceConfig() {
if (wfsServiceConfig == null) {
wfsServiceConfig = HarvesterServiceManager.getInstance()
.getServiceConfig(ServiceType.WFS);
}
return wfsServiceConfig;
}
}

View file

@ -4,6 +4,7 @@
<classpathentry kind="src" path="deploy"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="src" path="integration"/>
<classpathentry kind="src" path="manual"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.junit"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.apache.commons.codec"/>

View file

@ -0,0 +1,169 @@
/**
* 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.
**/
package com.raytheon.uf.common.comm;
import static org.junit.Assert.assertEquals;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.methods.HttpGet;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlets.ProxyServlet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.raytheon.uf.common.comm.HttpClient.HttpClientResponse;
import com.raytheon.uf.common.datadelivery.registry.Connection;
import com.raytheon.uf.common.datadelivery.registry.Connection.Encryption;
import com.raytheon.uf.common.datadelivery.registry.DataType;
import com.raytheon.uf.common.datadelivery.registry.Projection;
import com.raytheon.uf.common.datadelivery.registry.Provider;
import com.raytheon.uf.common.datadelivery.registry.Provider.ServiceType;
import com.raytheon.uf.common.datadelivery.registry.ProviderType;
import com.raytheon.uf.common.util.ProxiedJettyServer;
/**
* HttpClient test class. This case tests the https connection with valid
* credentials already provided.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 11, 2013 1763 dhladky Initial creation
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class HttpProxiedClientValidCredentialsTest {
private static ProxiedJettyServer server;
@Before
public void startHttpsServer() {
server = new ProxiedJettyServer(HttpProxyTestConstants.HTTP_URI,
HttpProxyTestConstants.HTTP_PORT,
HttpProxyTestConstants.HTTPS_PORT,
HttpProxyTestConstants.CONTEXT, HttpProxyTestConstants.REALM,
HttpProxyTestConstants.USERNAME, HttpProxyTestConstants.PASSWD);
// sample setup
ProxyServlet.Transparent servlet = new ProxyServlet.Transparent();
ServletHolder servletHolder = new ServletHolder(servlet);
servletHolder.setInitParameter("ProxyTo",
HttpProxyTestConstants.HTTP_URI);
servletHolder.setInitParameter("Prefix", "/"
+ HttpProxyTestConstants.CONTEXT);
server.addServlet(servletHolder, "/" + HttpProxyTestConstants.CONTEXT
+ "/*");
try {
server.startSSLServer();
} catch (Exception e) {
throw new RuntimeException("Error starting Jetty Server", e);
}
}
@After
public void stopServer() {
try {
server.stopServer();
} catch (Exception e) {
throw new RuntimeException("Error stopping Jetty Server", e);
}
}
@Test
public void testHttpsConnectionWithValidCredentials() {
int expectedCode = 200;
int actualCode = 200;
String xmlResponse;
HttpClient http = null;
try {
// Sets up any proxy info that might be necessary
// TODO: consider using HTTP POST instead of GET
http = HttpClient.getInstance();
http.setHandler(new TestHttpsCredentialsHandler());
http.setHttpsConfiguration(new TestHttpsConfiguration());
// connection object
Connection conn = new Connection();
conn.setUserName(HttpProxyTestConstants.USERNAME);
conn.setPassword(HttpProxyTestConstants.PASSWD);
conn.setEncryption(Encryption.CLEAR);
conn.setUrl(HttpProxyTestConstants.HTTPS_URI);
// projection object
Projection proj = new Projection();
proj.setName("MadisLatLon");
proj.setDescription("Madis test LatLon");
// provider
Provider provider = new Provider();
provider.setName(HttpProxyTestConstants.REALM);
provider.setServiceType(ServiceType.WFS);
provider.setConnection(conn);
// provider type
ProviderType pt = new ProviderType();
pt.setAvailabilityDelay(0);
pt.setDataType(DataType.POINT);
pt.setPlugin("madis");
List<ProviderType> types = new ArrayList<ProviderType>();
types.add(pt);
// addd the provider back
provider.setProviderType(types);
String url = HttpProxyTestConstants.HTTPS_URI
+ "?request=getfeature&typename=http://madis.edex.uf.raytheon.com:madis&srsName=crs:84&bbox=-96.0,41.0,-94.0,43.0&maxFeatures=1000";
Connection conn1 = provider.getConnection();
HttpGet get = new HttpGet();
URI uri = new URI(url);
// check for the need to do a username password auth check
if (conn1 != null && conn1.getUserName() != null
&& conn1.getPassword() != null) {
http.setCredentials(uri.getHost(), uri.getPort(),
provider.getName(), conn1.getUserName(),
conn1.getPassword());
System.out.println("Credentials set! " + conn1.getUserName()
+ " " + conn1.getPassword());
}
get.setURI(uri);
System.out.println("Get: " + get.getURI().toString());
HttpClientResponse response = http.executeRequest(get);
xmlResponse = new String(response.data);
System.out.println(xmlResponse);
} catch (Exception e) {
e.printStackTrace();
}
assertEquals(expectedCode, actualCode);
}
}

View file

@ -0,0 +1,64 @@
/**
* 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.
**/
package com.raytheon.uf.common.comm;
/**
* Http constants
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* June 11, 2013 1763 dhladky Initial creation
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class HttpProxyTestConstants {
public static final int HTTPS_PORT = 8888;
public static final String USERNAME = "user";
public static final String PASSWD = "password";
public static final String REALM = "MADISOGC";
public static final String CONTEXT = "wfs";
public static final String HOST = "dev11";
public static final String REMOTE_HOST = "dev05";
public static final int HTTP_PORT = 8085;
public static final String HTTPS_URI = "https://" + HOST + ":" + HTTPS_PORT
+ "/wfs";
public static final String HTTP_URI = "http://" + REMOTE_HOST + ":" + HTTP_PORT
+ "/wfs";
public static final int PORT = HTTP_PORT;
}

View file

@ -0,0 +1,61 @@
/**
* 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.
**/
package com.raytheon.uf.common.comm;
/**
* Test implementation.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 9, 2013 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class TestProxyHttpsConfiguration implements IHttpsConfiguration {
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.comm.IHttpsConfiguration#getHttpsPort()
*/
@Override
public int getHttpsPort() {
return HttpProxyTestConstants.HTTPS_PORT;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.comm.IHttpsConfiguration#getHttpPort()
*/
@Override
public int getHttpPort() {
return HttpProxyTestConstants.HTTP_PORT;
}
}

View file

@ -0,0 +1,47 @@
/**
* 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.
**/
package com.raytheon.uf.common.comm;
/**
* Test Https credentials handler. Returns valid credentials for HttpClient Test
* Cases.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* June 11, 2013 1763 dhladky Initial creation
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class TestProxyHttpsCredentialsHandler implements IHttpsCredentialsHandler {
@Override
public String[] getCredentials(String message) {
return new String[] { HttpProxyTestConstants.USERNAME,
HttpProxyTestConstants.PASSWD };
}
}

View file

@ -0,0 +1,232 @@
/**
* 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.
**/
package com.raytheon.uf.common.util;
import javax.servlet.Servlet;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlets.ProxyServlet;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Credential;
/**
* This class sets up a Jetty Server that can serve up Proxied HttpServlets in
* either http or https mode.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 11, 2013 dhladky Initial creation
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class ProxiedJettyServer {
/** The https port number */
private int httpsport = 8888;
/** HTTP port number */
private int httpport = 8085;
/** The realm string **/
private String realm;
/** Jetty server instance */
private Server server;
/** user for checks **/
private String user = "user";
/** password for checks **/
private String password = "password";
private final ServletContextHandler servletContextHandler;
/**
* Start the Proxied servlet
*
* @param redirectHost
* @param port
* @param context
* @param realm
* @param user
* @param password
*/
public ProxiedJettyServer(String redirectUrl, Integer httpport,
Integer httpsport, String context, String realm, String user,
String password) {
servletContextHandler = new ServletContextHandler(
ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
ProxyServlet.Transparent servlet = new ProxyServlet.Transparent();
ServletHolder servletHolder = new ServletHolder(servlet);
servletHolder.setInitParameter("ProxyTo", redirectUrl);
servletHolder.setInitParameter("Prefix", "/" + context);
addServlet(servletHolder, "/" + context + "/*");
this.httpport = httpport;
this.httpsport = httpsport;
this.realm = realm;
this.user = user;
this.password = password;
server = new Server();
}
/**
* Start the server as an SSL server
*
* @throws Exception
*/
public void startSSLServer() throws Exception {
String keystorePath = TestUtil.getFileForResource(JettyServer.class,
"/http/keystore").getAbsolutePath();
SslSocketConnector sslConnector = new SslSocketConnector();
sslConnector.setPort(httpsport);
sslConnector.setMaxIdleTime(30000);
sslConnector.setKeystore(keystorePath);
sslConnector.setPassword(password);
sslConnector.setKeyPassword(password);
sslConnector.setTruststore(keystorePath);
sslConnector.setTrustPassword(password);
server.addConnector(sslConnector);
servletContextHandler.setSecurityHandler(basicAuth(user, password,
realm));
server.setHandler(servletContextHandler);
server.start();
}
/**
* Start the server as a standard http server
*
* @throws Exception
*/
public void startServer() throws Exception {
server = new Server(httpsport);
server.setHandler(servletContextHandler);
server.start();
}
public void stopServer() throws Exception {
server.stop();
}
/**
* Add a servlet to the server.
*
* @param servlet
* The servlet to add
* @param pathSpec
* The path of the servlet
*/
public void addServlet(Servlet servlet, String pathSpec) {
addServlet(new ServletHolder(servlet), pathSpec);
}
public void addServlet(ServletHolder holder, String pathSpec) {
servletContextHandler.addServlet(holder, pathSpec);
}
/**
* Create a SecurityHandler for the SSL server.
*
* @param username
* The username
* @param password
* The password
* @param realm
* The realm name
* @return The SecurityHandler
*/
private final SecurityHandler basicAuth(String username, String password,
String realm) {
HashLoginService l = new HashLoginService();
l.putUser(username, Credential.getCredential(password),
new String[] { user });
l.setName(realm);
Constraint constraint = new Constraint();
constraint.setName(Constraint.__BASIC_AUTH);
constraint.setRoles(new String[] { user });
constraint.setAuthenticate(true);
ConstraintMapping cm = new ConstraintMapping();
cm.setConstraint(constraint);
cm.setPathSpec("/*");
ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
csh.setAuthenticator(new BasicAuthenticator());
csh.setRealmName(realm);
csh.addConstraintMapping(cm);
csh.setLoginService(l);
return csh;
}
private void addConnector(SelectChannelConnector connector) {
server.addConnector(connector);
}
private void setHandler(HandlerCollection handlers) {
server.setHandler(handlers);
}
// I kept this because I use it
public static void main(String[] args) throws Exception {
String redirectHost = args[0];
Integer port = Integer.parseInt(args[1]);
Integer sport = Integer.parseInt(args[2]);
String context = args[3];
String realm = args[4];
String user = args[5];
String password = args[6];
// Run this server
ProxiedJettyServer server = new ProxiedJettyServer(redirectHost, port,
sport, context, realm, user, password);
server.startServer();
}
}