/**
* Copyright (C) 2012-2017 52°North Initiative for Geospatial Open Source
* Software GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* If the program is linked with libraries which are licensed under one of
* the following licenses, the combination of the program with the linked
* library is not considered a "derivative work" of the program:
*
* - Apache License, version 2.0
* - Apache Software License, version 1.0
* - GNU Lesser General Public License, version 3
* - Mozilla Public License, versions 1.0, 1.1 and 2.0
* - Common Development and Distribution License (CDDL), version 1.0
*
* Therefore the distribution of the program linked with libraries licensed
* under the aforementioned licenses, is permitted by the copyright holders
* if the distribution is compliant with both the GNU General Public
* License version 2 and the aforementioned licenses.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*/
package org.n52.sos.ds.hibernate;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.Session;
import org.joda.time.DateTime;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.n52.sos.cache.ContentCache;
import org.n52.sos.config.SettingsManager;
import org.n52.sos.convert.ConverterException;
import org.n52.sos.ds.hibernate.dao.ProcedureDAO;
import org.n52.sos.ds.hibernate.entities.Procedure;
import org.n52.sos.ds.hibernate.util.TemporalRestrictions;
import org.n52.sos.ds.hibernate.util.procedure.HibernateProcedureConverter;
import org.n52.sos.event.SosEventBus;
import org.n52.sos.event.events.ObservationInsertion;
import org.n52.sos.event.events.ResultInsertion;
import org.n52.sos.event.events.ResultTemplateInsertion;
import org.n52.sos.event.events.SensorDeletion;
import org.n52.sos.event.events.SensorInsertion;
import org.n52.sos.ogc.filter.FilterConstants;
import org.n52.sos.ogc.filter.TemporalFilter;
import org.n52.sos.ogc.gml.CodeWithAuthority;
import org.n52.sos.ogc.gml.time.Time.TimeIndeterminateValue;
import org.n52.sos.ogc.gml.time.TimeInstant;
import org.n52.sos.ogc.om.ObservationValue;
import org.n52.sos.ogc.om.OmConstants;
import org.n52.sos.ogc.om.OmObservableProperty;
import org.n52.sos.ogc.om.OmObservation;
import org.n52.sos.ogc.om.OmObservationConstellation;
import org.n52.sos.ogc.om.SingleObservationValue;
import org.n52.sos.ogc.om.StreamingObservation;
import org.n52.sos.ogc.om.StreamingValue;
import org.n52.sos.ogc.om.features.SfConstants;
import org.n52.sos.ogc.om.features.samplingFeatures.SamplingFeature;
import org.n52.sos.ogc.om.values.QuantityValue;
import org.n52.sos.ogc.om.values.SweDataArrayValue;
import org.n52.sos.ogc.ows.OwsExceptionReport;
import org.n52.sos.ogc.sensorML.SensorMLConstants;
import org.n52.sos.ogc.sensorML.System;
import org.n52.sos.ogc.sos.Sos2Constants;
import org.n52.sos.ogc.sos.SosConstants;
import org.n52.sos.ogc.sos.SosInsertionMetadata;
import org.n52.sos.ogc.sos.SosOffering;
import org.n52.sos.ogc.sos.SosProcedureDescription;
import org.n52.sos.ogc.sos.SosResultEncoding;
import org.n52.sos.ogc.sos.SosResultStructure;
import org.n52.sos.ogc.swe.SweConstants;
import org.n52.sos.ogc.swe.SweDataArray;
import org.n52.sos.ogc.swe.SweDataRecord;
import org.n52.sos.ogc.swe.SweField;
import org.n52.sos.ogc.swe.encoding.SweTextEncoding;
import org.n52.sos.ogc.swe.simpleType.SweBoolean;
import org.n52.sos.ogc.swe.simpleType.SweCount;
import org.n52.sos.ogc.swe.simpleType.SweQuantity;
import org.n52.sos.ogc.swe.simpleType.SweTime;
import org.n52.sos.ogc.swes.SwesExtension;
import org.n52.sos.ogc.swes.SwesExtensionImpl;
import org.n52.sos.ogc.swes.SwesExtensions;
import org.n52.sos.request.DeleteSensorRequest;
import org.n52.sos.request.GetObservationRequest;
import org.n52.sos.request.InsertObservationRequest;
import org.n52.sos.request.InsertResultRequest;
import org.n52.sos.request.InsertResultTemplateRequest;
import org.n52.sos.request.InsertSensorRequest;
import org.n52.sos.request.operator.SosInsertObservationOperatorV20;
import org.n52.sos.response.DeleteSensorResponse;
import org.n52.sos.response.GetObservationResponse;
import org.n52.sos.response.InsertObservationResponse;
import org.n52.sos.response.InsertResultResponse;
import org.n52.sos.response.InsertResultTemplateResponse;
import org.n52.sos.response.InsertSensorResponse;
import org.n52.sos.service.Configurator;
import org.n52.sos.util.CodingHelper;
import org.n52.sos.util.CollectionHelper;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import net.opengis.sensorML.x101.SystemDocument;
import net.opengis.swe.x20.DataRecordDocument;
import net.opengis.swe.x20.TextEncodingDocument;
/**
* Test various Insert*DAOs using a common set of test data with hierarchical
* procedures. NOTE: These tests fail intermittently. They have been excluded
* from the normal build and set up to run multiple (100) times. They can be run
* directly from Eclipse or via Maven on the command line with the dao-test
* profile (mvn -P dao-test clean install)
*
* @author <a href="mailto:shane@axiomalaska.com">Shane StClair</a>
*
* @since 4.0.0
*
*/
@RunWith(Parameterized.class)
public class InsertDAOTest extends HibernateTestCase {
private static final String OFFERING1 = "offering1";
private static final String OFFERING2 = "offering2";
private static final String OFFERING3 = "offering3";
private static final String PROCEDURE1 = "procedure1";
private static final String PROCEDURE2 = "procedure2";
private static final String PROCEDURE3 = "procedure3";
private static final String OBSPROP1 = "obsprop1";
private static final String OBSPROP2 = "obsprop2";
private static final String OBSPROP3 = "obsprop3";
private static final String FEATURE3 = "feature3";
private static final String RESULT_TEMPLATE = "result_template";
private static final DateTime TIME1 = new DateTime("2013-07-18T00:00:00Z");
private static final DateTime TIME2 = new DateTime("2013-07-18T01:00:00Z");
private static final DateTime TIME3 = new DateTime("2013-07-18T02:00:00Z");
private static final DateTime OBS_TIME = new DateTime("2013-07-18T03:00:00Z");
private static final Double VAL1 = 19.1;
private static final Double VAL2 = 19.8;
private static final Double VAL3 = 20.4;
private static final Double OBS_VAL = 20.8;
private static final String TOKEN_SEPARATOR = ",";
private static final String DECIMAL_SEPARATOR = ".";
private static final String BLOCK_SEPARATOR = "#";
private static final String TEMP_UNIT = "Cel";
/* FIXTURES */
private InsertSensorDAO insertSensorDAO = new InsertSensorDAO();
private DeleteSensorDAO deleteSensorDAO = new DeleteSensorDAO();
private InsertObservationDAO insertObservationDAO = new InsertObservationDAO();
private InsertResultTemplateDAO insertResultTemplateDAO = new InsertResultTemplateDAO();
private InsertResultDAO insertResultDAO = new InsertResultDAO();
private GetObservationDAO getObsDAO = new GetObservationDAO();
private SosInsertObservationOperatorV20 insertObservationOperatorv2 = new SosInsertObservationOperatorV20();
// optionally run these tests multiple times to expose intermittent faults
// (use -DrepeatDaoTest=x)
@Parameterized.Parameters
public static List<Object[]> data() {
int repeatDaoTest = 1;
String repeatDaoTestStr = java.lang.System.getProperty("repeatDaoTest");
if (repeatDaoTestStr != null) {
repeatDaoTest = Integer.parseInt(repeatDaoTestStr);
}
return Arrays.asList(new Object[repeatDaoTest][0]);
}
@Before
public void setUp() throws OwsExceptionReport, ConverterException {
Session session = getSession();
insertSensor(PROCEDURE1, OFFERING1, OBSPROP1, null);
insertSensor(PROCEDURE2, OFFERING2, OBSPROP2, PROCEDURE1);
insertSensor(PROCEDURE3, OFFERING3, OBSPROP3, PROCEDURE2);
insertResultTemplate(RESULT_TEMPLATE, PROCEDURE3, OFFERING3, OBSPROP3, FEATURE3, getSession());
returnSession(session);
}
@After
public void tearDown() throws OwsExceptionReport, InterruptedException {
H2Configuration.truncate();
}
@AfterClass
public static void cleanUp() {
H2Configuration.recreate();
SettingsManager.getInstance().cleanup();
}
private void insertSensor(String procedure, String offering, String obsProp, String parentProcedure)
throws OwsExceptionReport {
InsertSensorRequest req = new InsertSensorRequest();
req.setAssignedProcedureIdentifier(procedure);
List<SosOffering> assignedOfferings = Lists.newLinkedList();
assignedOfferings.add(new SosOffering(offering, offering));
req.setObservableProperty(CollectionHelper.list(obsProp));
req.setProcedureDescriptionFormat(SensorMLConstants.NS_SML);
SosInsertionMetadata meta = new SosInsertionMetadata();
meta.setObservationTypes(Sets.newHashSet(OmConstants.OBS_TYPE_MEASUREMENT));
meta.setFeatureOfInterestTypes(Sets.newHashSet(SfConstants.SAMPLING_FEAT_TYPE_SF_SAMPLING_POINT));
req.setMetadata(meta);
System system = new System();
system.setIdentifier(procedure);
if (parentProcedure != null) {
system.addParentProcedure(parentProcedure);
for (String hierarchyParentProc : getCache().getParentProcedures(parentProcedure, true, true)) {
for (String parentProcOffering : getCache().getOfferingsForProcedure(hierarchyParentProc)) {
SosOffering sosOffering = new SosOffering(parentProcOffering, parentProcOffering);
sosOffering.setParentOfferingFlag(true);
assignedOfferings.add(sosOffering);
}
}
}
SystemDocument xbSystemDoc = SystemDocument.Factory.newInstance();
xbSystemDoc.addNewSystem().set(CodingHelper.encodeObjectToXml(SensorMLConstants.NS_SML, system));
system.setSensorDescriptionXmlString(xbSystemDoc.xmlText());
req.setProcedureDescription(system);
req.setAssignedOfferings(assignedOfferings);
InsertSensorResponse resp = insertSensorDAO.insertSensor(req);
SosEventBus.fire(new SensorInsertion(req, resp));
}
@SuppressWarnings("unused")
private void deleteSensor(String procedure) throws OwsExceptionReport {
DeleteSensorRequest req = new DeleteSensorRequest();
req.setProcedureIdentifier(procedure);
DeleteSensorResponse resp = deleteSensorDAO.deleteSensor(req);
SosEventBus.fire(new SensorDeletion(req, resp));
}
private void insertResultTemplate(String identifier, String procedureId, String offeringId, String obsPropId,
String featureId, Session session) throws OwsExceptionReport, ConverterException {
InsertResultTemplateRequest req = new InsertResultTemplateRequest();
req.setIdentifier(identifier);
req.setObservationTemplate(getOmObsConst(procedureId, obsPropId, TEMP_UNIT, offeringId, featureId,
OmConstants.OBS_TYPE_MEASUREMENT, session));
SweTextEncoding textEncoding = new SweTextEncoding();
textEncoding.setCollapseWhiteSpaces(false);
textEncoding.setDecimalSeparator(DECIMAL_SEPARATOR);
textEncoding.setTokenSeparator(TOKEN_SEPARATOR);
textEncoding.setBlockSeparator(BLOCK_SEPARATOR);
SosResultEncoding resultEncoding = new SosResultEncoding();
resultEncoding.setEncoding(textEncoding);
TextEncodingDocument xbTextEncDoc = TextEncodingDocument.Factory.newInstance();
xbTextEncDoc.addNewTextEncoding().set(CodingHelper.encodeObjectToXml(SweConstants.NS_SWE_20, textEncoding));
resultEncoding.getEncoding().setXml(xbTextEncDoc.xmlText());
req.setResultEncoding(resultEncoding);
SweDataRecord dataRecord = new SweDataRecord();
SweTime sweTime = new SweTime();
sweTime.setUom(OmConstants.PHEN_UOM_ISO8601);
sweTime.setDefinition(OmConstants.PHENOMENON_TIME);
dataRecord.addField(new SweField("time", sweTime));
SweQuantity airTemp = new SweQuantity();
airTemp.setDefinition(obsPropId);
airTemp.setUom(TEMP_UNIT);
dataRecord.addField(new SweField("air_temperature", airTemp));
SosResultStructure resultStructure = new SosResultStructure();
resultStructure.setResultStructure(dataRecord);
DataRecordDocument xbDataRecordDoc = DataRecordDocument.Factory.newInstance();
xbDataRecordDoc.addNewDataRecord().set(CodingHelper.encodeObjectToXml(SweConstants.NS_SWE_20, dataRecord));
resultStructure.getResultStructure().setXml(xbDataRecordDoc.xmlText());
req.setResultStructure(resultStructure);
InsertResultTemplateResponse resp = insertResultTemplateDAO.insertResultTemplate(req);
SosEventBus.fire(new ResultTemplateInsertion(req, resp));
}
private ContentCache getCache() {
return Configurator.getInstance().getCache();
}
private void updateCache() throws OwsExceptionReport {
Configurator.getInstance().getCacheController().update();
}
private OmObservationConstellation getOmObsConst(String procedureId, String obsPropId, String unit,
String offeringId, String featureId, String obsType, Session session) throws OwsExceptionReport,
ConverterException {
OmObservationConstellation obsConst = new OmObservationConstellation();
Procedure procedure = new ProcedureDAO().getProcedureForIdentifier(procedureId, session);
SosProcedureDescription spd =
new HibernateProcedureConverter().createSosProcedureDescription(procedure, SensorMLConstants.NS_SML,
Sos2Constants.SERVICEVERSION, session);
obsConst.setProcedure(spd);
OmObservableProperty omObservableProperty = new OmObservableProperty(obsPropId);
omObservableProperty.setUnit(unit);
obsConst.setObservableProperty(omObservableProperty);
obsConst.setFeatureOfInterest(new SamplingFeature(new CodeWithAuthority(featureId)));
obsConst.setObservationType(obsType);
if (!Strings.isNullOrEmpty(offeringId)) {
Set<String> offerings = new HashSet<String>();
offerings.add(offeringId);
obsConst.setOfferings(offerings);
}
return obsConst;
}
private String makeResultValueString(List<DateTime> times, List<Double> values) {
if (times.size() != values.size()) {
throw new RuntimeException("times and values must be the same length (times: " + times.size()
+ ", values: " + values.size() + ")");
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < times.size(); i++) {
if (i > 0) {
sb.append(BLOCK_SEPARATOR);
}
sb.append(times.get(i));
sb.append(TOKEN_SEPARATOR);
sb.append(values.get(i));
}
return sb.toString();
}
private void assertInsertionAftermathBeforeAndAfterCacheReload() throws OwsExceptionReport, InterruptedException {
// check once for cache changes triggered by sos event
assertInsertionAftermath();
// run a cache update
updateCache();
// check again after cache is reloaded
assertInsertionAftermath();
}
private void assertInsertionAftermath() throws OwsExceptionReport {
// check observation types
// assertThat(getCache().getObservationTypesForOffering(OFFERING1), contains(OmConstants.OBS_TYPE_MEASUREMENT));
// assertThat(getCache().getObservationTypesForOffering(OFFERING2), contains(OmConstants.OBS_TYPE_MEASUREMENT));
assertThat(getCache().getObservationTypesForOffering(OFFERING3), contains(OmConstants.OBS_TYPE_MEASUREMENT));
// check offerings for procedure
assertThat(getCache().getOfferingsForProcedure(PROCEDURE1), contains(OFFERING1));
assertThat(getCache().getOfferingsForProcedure(PROCEDURE2), containsInAnyOrder(OFFERING1, OFFERING2));
assertThat(getCache().getOfferingsForProcedure(PROCEDURE3),
containsInAnyOrder(OFFERING1, OFFERING2, OFFERING3));
// check procedures and hidden child procedures for offering
assertThat(getCache().getProceduresForOffering(OFFERING1), contains(PROCEDURE1));
assertThat(getCache().getHiddenChildProceduresForOffering(OFFERING1),
containsInAnyOrder(PROCEDURE2, PROCEDURE3));
assertThat(getCache().getProceduresForOffering(OFFERING2), contains(PROCEDURE2));
assertThat(getCache().getHiddenChildProceduresForOffering(OFFERING2), contains(PROCEDURE3));
assertThat(getCache().getProceduresForOffering(OFFERING3), contains(PROCEDURE3));
assertThat(getCache().getHiddenChildProceduresForOffering(OFFERING3), empty());
// check allowed observation types for offering
assertThat(getCache().getAllowedObservationTypesForOffering(OFFERING1),
contains(OmConstants.OBS_TYPE_MEASUREMENT));
assertThat(getCache().getAllowedObservationTypesForOffering(OFFERING2),
contains(OmConstants.OBS_TYPE_MEASUREMENT));
assertThat(getCache().getAllowedObservationTypesForOffering(OFFERING3),
contains(OmConstants.OBS_TYPE_MEASUREMENT));
// check parent procedures
assertThat(getCache().getParentProcedures(PROCEDURE1, true, false), empty());
assertThat(getCache().getParentProcedures(PROCEDURE2, true, false), contains(PROCEDURE1));
assertThat(getCache().getParentProcedures(PROCEDURE3, true, false), containsInAnyOrder(PROCEDURE1, PROCEDURE2));
// check child procedures
assertThat(getCache().getChildProcedures(PROCEDURE1, true, false), containsInAnyOrder(PROCEDURE2, PROCEDURE3));
assertThat(getCache().getChildProcedures(PROCEDURE2, true, false), contains(PROCEDURE3));
assertThat(getCache().getChildProcedures(PROCEDURE3, true, false), empty());
// check features of interest for offering
// TODO add geometries to features, check bounds, etc
// TODO investigate these, getting guid back instead of assigned
// identifier
// assertThat(getCache().getFeaturesOfInterestForOffering(OFFERING1),
// contains(FEATURE3));
// assertThat(getCache().getFeaturesOfInterestForOffering(OFFERING2),
// contains(FEATURE3));
// assertThat(getCache().getFeaturesOfInterestForOffering(OFFERING3),
// contains(FEATURE3));
// check obsprops for offering
assertThat(getCache().getObservablePropertiesForOffering(OFFERING1),
containsInAnyOrder(OBSPROP1, OBSPROP2, OBSPROP3));
assertThat(getCache().getObservablePropertiesForOffering(OFFERING2), containsInAnyOrder(OBSPROP2, OBSPROP3));
assertThat(getCache().getObservablePropertiesForOffering(OFFERING3), contains(OBSPROP3));
// check offering for obsprops
assertThat(getCache().getOfferingsForObservableProperty(OBSPROP1), contains(OFFERING1));
assertThat(getCache().getOfferingsForObservableProperty(OBSPROP2), containsInAnyOrder(OFFERING1, OFFERING2));
assertThat(getCache().getOfferingsForObservableProperty(OBSPROP3),
containsInAnyOrder(OFFERING1, OFFERING2, OFFERING3));
// check obsprops for procedure
// TODO child procedure obsprops are not currently set for parents.
// should they be?
// assertThat(getCache().getObservablePropertiesForProcedure(PROCEDURE1),
// containsInAnyOrder(OBSPROP1, OBSPROP2, OBSPROP3));
// assertThat(getCache().getObservablePropertiesForProcedure(PROCEDURE2),
// containsInAnyOrder(OBSPROP2, OBSPROP3));
assertThat(getCache().getObservablePropertiesForProcedure(PROCEDURE3), contains(OBSPROP3));
// check procedures for obsprop
// TODO child procedure obsprops are not currently set for parents.
// should they be?
assertThat(getCache().getProceduresForObservableProperty(OBSPROP1), contains(PROCEDURE1));
// assertThat(getCache().getProceduresForObservableProperty(OBSPROP2),
// containsInAnyOrder(PROCEDURE1, PROCEDURE2));
// assertThat(getCache().getProceduresForObservableProperty(OBSPROP3),
// containsInAnyOrder(PROCEDURE1, PROCEDURE2, PROCEDURE3));
// check procedures for feature
// TODO child procedure features are not currently set for parents.
// should they be?
// assertThat(getCache().getProceduresForFeatureOfInterest(FEATURE3),
// containsInAnyOrder(PROCEDURE1, PROCEDURE2, PROCEDURE3));
}
@Test
public void testCacheContents() throws OwsExceptionReport {
assertThat(getCache().getProcedures(), containsInAnyOrder(PROCEDURE1, PROCEDURE2, PROCEDURE3));
assertThat(getCache().getOfferings(), containsInAnyOrder(OFFERING1, OFFERING2, OFFERING3));
assertThat(getCache().getObservableProperties(), containsInAnyOrder(OBSPROP1, OBSPROP2, OBSPROP3));
assertThat(getCache().getParentProcedures(PROCEDURE3, true, false), containsInAnyOrder(PROCEDURE1, PROCEDURE2));
assertThat(getCache().getResultTemplatesForOffering(OFFERING3).size(), is(1));
}
@Test
public void testInsertObservation() throws OwsExceptionReport, InterruptedException, ConverterException {
InsertObservationRequest req = new InsertObservationRequest();
req.setAssignedSensorId(PROCEDURE3);
req.setOfferings(Lists.newArrayList(OFFERING3));
OmObservation obs = new OmObservation();
Session session = getSession();
obs.setObservationConstellation(getOmObsConst(PROCEDURE3, OBSPROP3, TEMP_UNIT, OFFERING3, FEATURE3,
OmConstants.OBS_TYPE_MEASUREMENT, session));
returnSession(session);
obs.setResultTime(new TimeInstant(OBS_TIME));
SingleObservationValue<Double> obsVal = new SingleObservationValue<Double>();
obsVal.setPhenomenonTime(new TimeInstant(OBS_TIME));
obsVal.setValue(new QuantityValue(Double.valueOf(OBS_VAL), TEMP_UNIT));
obs.setValue(obsVal);
req.setObservation(Lists.newArrayList(obs));
InsertObservationResponse resp = insertObservationDAO.insertObservation(req);
SosEventBus.fire(new ObservationInsertion(req, resp));
assertInsertionAftermathBeforeAndAfterCacheReload();
// TODO requests for the parent procedures fail?
// checkObservation(OFFERING1, PROCEDURE1, OBSPROP3, OBS_TIME,
// PROCEDURE3, OBSPROP3, FEATURE3,
// OBS_VAL, TEMP_UNIT);
// checkObservation(OFFERING2, PROCEDURE2, OBSPROP3, OBS_TIME,
// PROCEDURE3, OBSPROP3, FEATURE3,
// OBS_VAL, TEMP_UNIT);
checkObservation(Lists.newArrayList(OFFERING1, OFFERING2, OFFERING3), PROCEDURE3, OBSPROP3, OBS_TIME, PROCEDURE3, OBSPROP3, FEATURE3, OBS_VAL, TEMP_UNIT);
checkObservation(Lists.newArrayList(OFFERING2, OFFERING3), PROCEDURE3, OBSPROP3, OBS_TIME, PROCEDURE3, OBSPROP3, FEATURE3, OBS_VAL, TEMP_UNIT);
checkObservation(OFFERING3, PROCEDURE3, OBSPROP3, OBS_TIME, PROCEDURE3, OBSPROP3, FEATURE3, OBS_VAL, TEMP_UNIT);
}
/**
* Check results of an InsertObservation request with
* SplitDataArrayIntoObservations
*/
// TODO should this test live in another module, since it involves
// transactional-v20?
// however, it also tests functionality.
@Test
public void testInsertObservationWithSplit() throws OwsExceptionReport, InterruptedException, ConverterException {
InsertObservationRequest req = new InsertObservationRequest();
req.setService(SosConstants.SOS);
req.setVersion(Sos2Constants.SERVICEVERSION);
SwesExtension<SweBoolean> splitExt = new SwesExtensionImpl<SweBoolean>();
splitExt.setDefinition(Sos2Constants.Extensions.SplitDataArrayIntoObservations.name());
splitExt.setValue(new SweBoolean().setValue(Boolean.TRUE));
SwesExtensions swesExtensions = new SwesExtensions();
swesExtensions.addSwesExtension(splitExt);
req.setExtensions(swesExtensions);
req.setAssignedSensorId(PROCEDURE3);
req.setOfferings(Lists.newArrayList(OFFERING3));
OmObservation obs = new OmObservation();
Session session = getSession();
obs.setObservationConstellation(getOmObsConst(PROCEDURE3, OBSPROP3, TEMP_UNIT, OFFERING3, FEATURE3,
OmConstants.OBS_TYPE_SWE_ARRAY_OBSERVATION, session));
returnSession(session);
obs.setResultTime(new TimeInstant(null, TimeIndeterminateValue.template));
SweDataArrayValue sweDataArrayValue = new SweDataArrayValue();
SweDataArray sweDataArray = new SweDataArray();
sweDataArray.setElementCount(new SweCount().setValue(3));
SweDataRecord sweDataRecord = new SweDataRecord();
SweTime time = new SweTime();
time.setDefinition(OmConstants.PHENOMENON_TIME);
time.setUom(OmConstants.PHEN_UOM_ISO8601);
SweField timeField = new SweField(OmConstants.PHENOMENON_TIME_NAME, time);
sweDataRecord.addField(timeField);
SweQuantity temp = new SweQuantity();
temp.setDefinition(OBSPROP3);
temp.setUom(TEMP_UNIT);
SweField tempField = new SweField(OmConstants.EN_OBSERVED_PROPERTY, temp);
sweDataRecord.addField(tempField);
sweDataArray.setElementType(sweDataRecord);
SweTextEncoding sweTextEncoding = new SweTextEncoding();
sweTextEncoding.setBlockSeparator("#");
sweTextEncoding.setDecimalSeparator(".");
sweTextEncoding.setTokenSeparator("@");
sweDataArray.setEncoding(sweTextEncoding);
// add values
sweDataArray.add(CollectionHelper.list(TIME1.toString(), Double.toString(VAL1)));
sweDataArray.add(CollectionHelper.list(TIME2.toString(), Double.toString(VAL2)));
sweDataArray.add(CollectionHelper.list(TIME3.toString(), Double.toString(VAL3)));
sweDataArrayValue.setValue(sweDataArray);
SingleObservationValue<SweDataArray> obsVal = new SingleObservationValue<SweDataArray>();
obsVal.setPhenomenonTime(new TimeInstant(null, TimeIndeterminateValue.template));
obsVal.setValue(sweDataArrayValue);
obs.setValue(obsVal);
req.setObservation(Lists.newArrayList(obs));
insertObservationOperatorv2.receive(req);
assertInsertionAftermathBeforeAndAfterCacheReload();
checkObservation(OFFERING3, PROCEDURE3, OBSPROP3, TIME1, PROCEDURE3, OBSPROP3, FEATURE3, VAL1, TEMP_UNIT);
checkObservation(OFFERING3, PROCEDURE3, OBSPROP3, TIME2, PROCEDURE3, OBSPROP3, FEATURE3, VAL2, TEMP_UNIT);
checkObservation(OFFERING3, PROCEDURE3, OBSPROP3, TIME3, PROCEDURE3, OBSPROP3, FEATURE3, VAL3, TEMP_UNIT);
}
@Test
public void testInsertResult() throws OwsExceptionReport, InterruptedException {
InsertResultRequest req = new InsertResultRequest();
req.setTemplateIdentifier(RESULT_TEMPLATE);
req.setResultValues(makeResultValueString(CollectionHelper.list(TIME1, TIME2, TIME3),
CollectionHelper.list(VAL1, VAL2, VAL3)));
InsertResultResponse resp = insertResultDAO.insertResult(req);
SosEventBus.fire(new ResultInsertion(req, resp));
assertInsertionAftermathBeforeAndAfterCacheReload();
checkObservation(OFFERING3, PROCEDURE3, OBSPROP3, TIME1, PROCEDURE3, OBSPROP3, FEATURE3, VAL1, TEMP_UNIT);
checkObservation(OFFERING3, PROCEDURE3, OBSPROP3, TIME2, PROCEDURE3, OBSPROP3, FEATURE3, VAL2, TEMP_UNIT);
checkObservation(OFFERING3, PROCEDURE3, OBSPROP3, TIME3, PROCEDURE3, OBSPROP3, FEATURE3, VAL3, TEMP_UNIT);
}
private void checkObservation(String reqOffering, String reqProcedure, String reqObsProp, DateTime time,
String obsProcedure, String obsObsProp, String obsFeature, Double obsVal, String obsUnit)
throws OwsExceptionReport {
checkObservation(Lists.newArrayList(reqOffering), reqProcedure, reqObsProp, time,
obsProcedure, obsObsProp, obsFeature, obsVal, obsUnit);
}
private void checkObservation(List<String> reqOffering, String reqProcedure, String reqObsProp, DateTime time,
String obsProcedure, String obsObsProp, String obsFeature, Double obsVal, String obsUnit)
throws OwsExceptionReport {
GetObservationRequest getObsReq = new GetObservationRequest();
getObsReq.setOfferings(reqOffering);
getObsReq.setProcedures(CollectionHelper.list(reqProcedure));
getObsReq.setObservedProperties(CollectionHelper.list(reqObsProp));
getObsReq.setResponseFormat(OmConstants.NS_OM_2);
TemporalFilter tempFilter =
new TemporalFilter(FilterConstants.TimeOperator.TM_Equals, new TimeInstant(time),
TemporalRestrictions.PHENOMENON_TIME_VALUE_REFERENCE);
getObsReq.setTemporalFilters(CollectionHelper.list(tempFilter));
getObsReq.setService(SosConstants.SOS);
getObsReq.setVersion(Sos2Constants.SERVICEVERSION);
GetObservationResponse getObsResponse = getObsDAO.getObservation(getObsReq);
assertThat(getObsResponse, notNullValue());
assertThat(getObsResponse.getObservationCollection().isEmpty(), is(false));
OmObservation omObservation = getObsResponse.getObservationCollection().get(0);
if (omObservation.getValue() instanceof StreamingObservation) {
assertThat(((StreamingObservation)omObservation.getValue()).hasNextValue(), is(true));
omObservation = ((StreamingObservation)omObservation.getValue()).nextSingleObservation();
assertThat(omObservation.getObservationConstellation(), notNullValue());
OmObservationConstellation obsConst = omObservation.getObservationConstellation();
assertThat(obsConst.getProcedure().getIdentifier(), is(obsProcedure));
assertThat(obsConst.getObservableProperty().getIdentifier(), is(obsObsProp));
// TODO this fails
// assertThat(obsConst.getFeatureOfInterest().getIdentifier().getValue(),
// is(obsFeature));
assertThat(omObservation.getValue(), notNullValue());
ObservationValue<?> value = omObservation.getValue();
assertThat(value.getValue(), instanceOf(QuantityValue.class));
assertThat(value.getPhenomenonTime(), instanceOf(TimeInstant.class));
TimeInstant timeInstant = (TimeInstant) value.getPhenomenonTime();
assertThat(timeInstant.getValue().toDate(), is(time.toDate()));
QuantityValue quantityValue = (QuantityValue) value.getValue();
assertThat(quantityValue.getValue().doubleValue(), is(obsVal));
assertThat(quantityValue.getUnit(), is(obsUnit));
// TODO
} else if (omObservation.getValue() instanceof StreamingValue) {
assertThat(((StreamingValue)omObservation.getValue()).hasNextValue(), is(true));
omObservation = ((StreamingValue)omObservation.getValue()).nextSingleObservation();
assertThat(omObservation, notNullValue());
assertThat(omObservation.getObservationConstellation(), notNullValue());
OmObservationConstellation obsConst = omObservation.getObservationConstellation();
assertThat(obsConst.getProcedure().getIdentifier(), is(obsProcedure));
assertThat(obsConst.getObservableProperty().getIdentifier(), is(obsObsProp));
// TODO this fails
// assertThat(obsConst.getFeatureOfInterest().getIdentifier().getValue(),
// is(obsFeature));
assertThat(omObservation.getValue(), notNullValue());
ObservationValue<?> value = omObservation.getValue();
assertThat(value.getValue(), instanceOf(QuantityValue.class));
assertThat(value.getPhenomenonTime(), instanceOf(TimeInstant.class));
TimeInstant timeInstant = (TimeInstant) value.getPhenomenonTime();
assertThat(timeInstant.getValue().toDate(), is(time.toDate()));
QuantityValue quantityValue = (QuantityValue) value.getValue();
assertThat(quantityValue.getValue().doubleValue(), is(obsVal));
assertThat(quantityValue.getUnit(), is(obsUnit));
} else {
assertThat(omObservation.getObservationConstellation(), notNullValue());
OmObservationConstellation obsConst = omObservation.getObservationConstellation();
assertThat(obsConst.getProcedure().getIdentifier(), is(obsProcedure));
assertThat(obsConst.getObservableProperty().getIdentifier(), is(obsObsProp));
// TODO this fails
// assertThat(obsConst.getFeatureOfInterest().getIdentifier().getValue(),
// is(obsFeature));
assertThat(omObservation.getValue(), notNullValue());
ObservationValue<?> value = omObservation.getValue();
assertThat(value.getValue(), instanceOf(QuantityValue.class));
assertThat(value.getPhenomenonTime(), instanceOf(TimeInstant.class));
TimeInstant timeInstant = (TimeInstant) value.getPhenomenonTime();
assertThat(timeInstant.getValue().toDate(), is(time.toDate()));
QuantityValue quantityValue = (QuantityValue) value.getValue();
assertThat(quantityValue.getValue().doubleValue(), is(obsVal));
assertThat(quantityValue.getUnit(), is(obsUnit));
}
}
}