package au.org.aurin.wif.io; import static org.geotools.jdbc.JDBCDataStoreFactory.DATABASE; import static org.geotools.jdbc.JDBCDataStoreFactory.HOST; import static org.geotools.jdbc.JDBCDataStoreFactory.SCHEMA; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; import java.util.UUID; import javax.annotation.PostConstruct; import javax.annotation.Resource; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFinder; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureSource; import org.geotools.geojson.feature.FeatureJSON; import org.geotools.geojson.geom.GeometryJSON; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import au.org.aurin.wif.config.WifConfig; import au.org.aurin.wif.exception.io.DataStoreCreationException; import au.org.aurin.wif.exception.io.MiddlewarePersistentException; import au.org.aurin.wif.model.WifProject; import au.org.aurin.wif.restclient.AurinServiceClient; import au.org.aurin.wif.svc.WifKeys; /** * The Class DataStoreToPostgisExporter. */ @Component public class PostgisToDataStoreExporter { /** The Constant LOGGER. */ private static final Logger LOGGER = LoggerFactory .getLogger(PostgisToDataStoreExporter.class); /** The data store client. */ @Autowired private DataStoreClient dataStoreClient; /** The file to postgis exporter. */ @Autowired private FileToPostgisExporter fileToPostgisExporter; /** The wif config. */ @Resource private WifConfig wifConfig; /** The postgis data store config. */ @Autowired @Qualifier("wifDataStoreConfig") private PostgisDataStoreConfig postgisDataStoreConfig; /** The project service. */ @Resource private AurinServiceClient aurinServiceClient; /** * Inits the sservice. */ @PostConstruct public void init() { LOGGER.trace("Initializing version: " + WifKeys.WIF_KEY_VERSION); LOGGER.info("using the following server: {} for database/schema: {}", postgisDataStoreConfig.getDataStoreParams().get(HOST.key), postgisDataStoreConfig.getDataStoreParams().get(DATABASE.key) + "/" + postgisDataStoreConfig.getDataStoreParams().get(SCHEMA.key)); } /** * Export uaz. * * @param project * the project * @param userId * the user id * @return the string * @throws IOException * Signals that an I/O exception has occurred. * @throws DataStoreCreationException * the data store creation exception * @throws MiddlewarePersistentException */ public String exportUAZ(final WifProject project, final String userId) throws IOException, DataStoreCreationException, MiddlewarePersistentException { LOGGER.info("Entering exportUAZ/share in my aurin"); LOGGER.info("using the following server: {} for database/schema: {}", postgisDataStoreConfig.getDataStoreParams().get(HOST.key), postgisDataStoreConfig.getDataStoreParams().get(DATABASE.key) + "/" + postgisDataStoreConfig.getDataStoreParams().get(SCHEMA.key)); final String tableName = project.getSuitabilityConfig() .getUnifiedAreaZone(); final DataStore dataStore = DataStoreFinder .getDataStore(postgisDataStoreConfig.getDataStoreParams()); final SimpleFeatureSource featureSource = dataStore .getFeatureSource(tableName); final SimpleFeatureCollection features = featureSource.getFeatures(); final String result = shareUAZSnapshot(features, userId, project); LOGGER .info("exporting finished, information sent to AURIN/middleware persistence!"); return result; } /** * Upload features. * * @param features * the features * @param userId * the user id * @param project * @return the string * @throws IOException * Signals that an I/O exception has occurred. * @throws DataStoreCreationException * the data store creation exception * @throws MiddlewarePersistentException */ private String shareUAZSnapshot(final SimpleFeatureCollection features, final String userId, final WifProject project) throws IOException, DataStoreCreationException, MiddlewarePersistentException { // TODO the following chunk of code is from Mohammed, we should have these // in a shared library final int decimals = WifKeys.GEOJSON_PRECISION; final GeometryJSON gjson = new GeometryJSON(decimals); final FeatureJSON featureJSON = new FeatureJSON(gjson); featureJSON.setEncodeFeatureCollectionBounds(true); featureJSON.setEncodeFeatureCollectionCRS(true); featureJSON.setEncodeNullValues(true); final String uuid = UUID.randomUUID().toString(); // Get the temporary directory and print it. final String tempDir = System.getProperty("java.io.tmpdir"); final File tmpFile = new File(tempDir + "/" + uuid + ".json"); if (!tmpFile.exists()) { tmpFile.createNewFile(); LOGGER.info(tmpFile.getAbsolutePath() + " has been created"); } final OutputStream output = new BufferedOutputStream(new FileOutputStream( tmpFile)); // TODO end the chunk code from Mohammed // FIXME the following operation tthrow a // org.geotools.data.postgis.PostGISDialect getOptimizedBounds // WARNING: Failed to use ST_Estimated_Extent, falling back on envelope // aggregation // org.postgresql.util.PSQLException: ERROR: LWGEOM_estimated_extent: // couldn't locate table within current schema // Nonetheless, this a known issue of geotools when working with psotgis of // earlier versions of 1.5 featureJSON.writeFeatureCollection(features, output);// output LOGGER.info("done writing feature collection..." + tmpFile.length() / 1024 / 1024 + " MB."); final Map<String, Object> item = aurinServiceClient.shareAurinProject( tmpFile, userId, project); LOGGER.debug("response " + item.get("result")); return (String) item.get("result"); } /** * Persist in aurin creating an item for middleware with the following format: * { "id": "uuid4(), what-if projectId that would be used in items", "userId": * "ivow", "projectId": "project-meta", "timeStamp": "<system-generated>", * "data": { "type": "meta", "name": "Project Name", "description": * "Project description", } } * * @param project * the project * @param userId * the user id * @param datastoreUri * the datastore uri * @throws MiddlewarePersistentException */ public void persistInAurin(final WifProject project, final String userId) throws MiddlewarePersistentException { final Map<String, Object> item = new HashMap<String, Object>(); item.put("userId", userId); item.put("projectId", "project-meta-whatif"); final Map<String, Object> metadata = new HashMap<String, Object>(); metadata.put("type", "meta"); metadata.put("name", project.getName()); // TODO Have a common date format for AURIN item.put("timeStamp", new SimpleDateFormat().format(project.getCreationDate())); metadata.put("description", project.getStudyArea()); item.put("data", metadata); aurinServiceClient.sendPersistenceItem(item, userId); } }