V1_0.java [src/java/m/DSSATProxy] Revision: default Date:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package m.DSSATProxy;
import csip.utils.Client;
import csip.Config;
import csip.annotations.*;
import csip.ModelDataService;
import csip.api.server.PayloadParameter;
import csip.api.server.ServiceException;
import javax.ws.rs.Path;
import csip.utils.ZipFiles;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.codehaus.jettison.json.JSONArray;
@Name("DSSAT Proxy Service")
@Description("DSSAT SUBSTOR csip service")
@VersionInfo("1.0")
@Path("m/dssatproxy/1.0")
@Options(timeout = "P2H")
public class V1_0 extends ModelDataService {
static final String KEY_FILE = "param";
static final String SIM_TYPE = "simulation_type";
static final String KEY_LOGLEVEL = "loglevel";
static final String ID_SOIL = "id_soil";
static final String ID_WEATHER = "wsta....";
static final String LONGITUDE = "longitude";
static final String LATITUDE = "latitude";
static final String FILE_NAME = "file_name";
static final String COKEY = "cokey";
static final String START_DATE_OLD = "start_date_old";
static final String START_DATE = "start_date"; //NEW START DATE
static final String END_DATE = "end_date";
@Override
protected void doProcess() throws Exception {
PayloadParameter jsonRequest = parameter();
double longitude;
double latitude;
String start_date_old;
String start_date;
String end_date;
String paramFile;
String cokey;
String simulation_type;
String dssatReplacedateUrl;
String dssatUrl;
try {
paramFile = jsonRequest.getString(KEY_FILE);
longitude = jsonRequest.getDouble(LONGITUDE);
latitude = jsonRequest.getDouble(LATITUDE);
cokey = jsonRequest.getString(COKEY);
start_date_old = jsonRequest.getString(START_DATE_OLD);
start_date = jsonRequest.getString(START_DATE);
end_date = jsonRequest.getString(END_DATE);
simulation_type = jsonRequest.getString(SIM_TYPE);
} catch (ServiceException ex) {
throw new RuntimeException(ex);
}
dssatReplacedateUrl = Config.getString("dssat.replacedate.service");
dssatUrl = Config.getString("dssat.dssat.service");
this.callReplaceDateService(dssatReplacedateUrl, start_date_old, start_date);
// request csip-dssat
// to attach json, consider https://stackoverflow.com/questions/22668660/embedding-a-file-attachment-in-json-object
// unpack response
this.callDSSATService(dssatUrl, paramFile, simulation_type, longitude, latitude, cokey, start_date, end_date);
}
@Override
protected void postProcess() throws Exception {
File zip = ZipFiles.zip(new File(workspace().getDir().getAbsolutePath()));
results().put(zip);
}
private JSONObject getRequestObjForReplaceDates(String start_date_old, String start_date) throws JSONException {
JSONObject requestObj = new JSONObject();
JSONArray paramObj = new JSONArray();
JSONObject startDateOldJSON = new JSONObject();
JSONObject startDateJSON = new JSONObject();
startDateOldJSON.put(KEY_NAME, START_DATE_OLD);
startDateOldJSON.put(VALUE, start_date_old);
paramObj.put(startDateOldJSON);
startDateJSON.put(KEY_NAME, START_DATE);
startDateJSON.put(VALUE, start_date);
paramObj.put(startDateJSON);
requestObj.put(KEY_PARAMETER, paramObj);
return requestObj;
}
private void callReplaceDateService(String url, String start_date_old, String start_date) throws IOException, Exception {
JSONObject requestObj = this.getRequestObjForReplaceDates(start_date_old, start_date);
JSONObject returnObj;
LOG.info("DSSAT Request: " + requestObj.toString());
File zip = ZipFiles.zip(new File(workspace().getDir().getAbsolutePath()));
returnObj = new Client().doPOST(Config.getString("DSSAT replacedate", url), requestObj, new File[]{zip});
LOG.info("DSSAT Response: " + returnObj.toString());
JSONObject responseMeta = returnObj.getJSONObject(KEY_METAINFO);
if (!responseMeta.getString(KEY_STATUS).equalsIgnoreCase(FAILED)) {
JSONArray resultsObj = returnObj.getJSONArray("result");
boolean fileFound = false;
String resultsZipFileName = "";
JSONObject currJSONObj;
boolean zipFileFound = false;
for (int i = 0; i < resultsObj.length(); i++) {
currJSONObj = resultsObj.getJSONObject(i);
if (!zipFileFound && ("" + currJSONObj).toLowerCase().contains("zip")) {
fileFound = true;
resultsZipFileName = currJSONObj.getString("value");
//alternative way to pull the zip
/*
String[] zipFileNameArray = currJSONObj.getString("value").split("/");
resultsZipFileName = zipFileNameArray[zipFileNameArray.length - 1];*/
zipFileFound = true;
continue;
}
// results().put(currJSONObj.getString("name"), currJSONObj.get("value"));
}
if (fileFound) {
File resultsZipFile = new File(workspace().getDir(), "resultData.zip");
//alternative way to pull the zip
/*URI soil = new URI(JSONUtils.getStringParam(resultList, resultsZipFileName, ""));
new Client().doGET(soil.toString(), resultsZipFile);*/
new Client().doGET(resultsZipFileName, resultsZipFile);
ZipFiles.unzip(resultsZipFile);
resultsZipFile.delete();
}
}
}
//utility methods
//returns a copy of the request object
private JSONObject getRequestObjForDSSAT(String paramFile, String simulation_type, double longitude, double latitude, String cokey, String start_date, String end_date) {
JSONObject requestObj = new JSONObject();
try {
JSONArray paramObj = new JSONArray();
JSONObject keyFileJSON = new JSONObject();
JSONObject simTypeJSON = new JSONObject();
JSONObject longitudeJSON = new JSONObject();
JSONObject latitudeJSON = new JSONObject();
JSONObject cokeyJSON = new JSONObject();
JSONObject startDateJSON = new JSONObject();
JSONObject endDateJSON = new JSONObject();
keyFileJSON.put("name", KEY_FILE);
keyFileJSON.put("value", paramFile);
paramObj.put(keyFileJSON);
simTypeJSON.put("name", SIM_TYPE);
simTypeJSON.put("value", simulation_type);
paramObj.put(simTypeJSON);
longitudeJSON.put("name", LONGITUDE);
longitudeJSON.put("value", longitude);
paramObj.put(longitudeJSON);
latitudeJSON.put("name", LATITUDE);
latitudeJSON.put("value", latitude);
paramObj.put(latitudeJSON);
cokeyJSON.put("name", COKEY);
cokeyJSON.put("value", cokey);
paramObj.put(cokeyJSON);
startDateJSON.put("name", START_DATE);
startDateJSON.put("value", start_date);
paramObj.put(startDateJSON);
endDateJSON.put("name", END_DATE);
endDateJSON.put("value", end_date);
paramObj.put(endDateJSON);
requestObj.put(KEY_PARAMETER, paramObj);
} catch (JSONException ex) {
Logger.getLogger(V1_0.class.getName()).log(Level.SEVERE, null, ex);
}
return requestObj;
}
//calls DSSAT service with a request JSON object (and unpacks it?)
private void callDSSATService(String url, String paramFile, String simulation_type, double longitude, double latitude, String cokey, String start_date, String end_date) throws Exception {
JSONObject requestObj = this.getRequestObjForDSSAT(paramFile, simulation_type, longitude, latitude, cokey, start_date, end_date);
JSONObject returnObj;
LOG.info("DSSAT Request: " + requestObj.toString());
File zip = ZipFiles.zip(new File(workspace().getDir().getAbsolutePath()));
returnObj = new Client().doPOST(Config.getString("DSSAT daymet", url), requestObj, new File[]{zip});
LOG.info("DSSAT Response: " + returnObj.toString());
JSONObject responseMeta = returnObj.getJSONObject(KEY_METAINFO);
if (!responseMeta.getString(KEY_STATUS).equalsIgnoreCase(FAILED)) {
JSONArray resultsObj = returnObj.getJSONArray("result");
boolean fileFound = false;
String resultsZipFileName = "";
JSONObject currJSONObj;
boolean zipFileFound = false;
for (int i = 0; i < resultsObj.length(); i++) {
currJSONObj = resultsObj.getJSONObject(i);
if (!zipFileFound && ("" + currJSONObj).toLowerCase().contains("zip")) {
fileFound = true;
resultsZipFileName = currJSONObj.getString("value");
//alternative way to pull the zip
/*
String[] zipFileNameArray = currJSONObj.getString("value").split("/");
resultsZipFileName = zipFileNameArray[zipFileNameArray.length - 1];*/
zipFileFound = true;
continue;
}
results().put(currJSONObj.getString("name"), currJSONObj.get("value"));
}
if (fileFound) {
File resultsZipFile = new File(workspace().getDir(), "resultData.zip");
//alternative way to pull the zip
/*URI soil = new URI(JSONUtils.getStringParam(resultList, resultsZipFileName, ""));
new Client().doGET(soil.toString(), resultsZipFile);*/
new Client().doGET(resultsZipFileName, resultsZipFile);
ZipFiles.unzip(resultsZipFile);
resultsZipFile.delete();
}
}
}
private static ArrayList<File> listContentsOfZipFile(String zipFileName) {
ArrayList<File> fileList = new ArrayList();
try {
ZipFile zipFile = new ZipFile(zipFileName);
Enumeration<?> enu = zipFile.entries();
while (enu.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enu.nextElement();
fileList.add(new File(zipEntry.getName()));
}
zipFile.close();
} catch (IOException e) {
e.printStackTrace();
}
return fileList;
}
// deletes all the files in the current folder that correspond to the files
// in the zip file namedzipFileName
private static void cleanUp(String zipFileName) {
ArrayList<File> filesToDelete = listContentsOfZipFile(zipFileName);
for (File currentFile : filesToDelete) {
if (currentFile.delete()) {
System.out.println(currentFile + " was deleted successfully!");
}
}
}
//renames old file name to new file name
private static void renameFile(String oldFilePath, String newFilePath) {
File currFile = new File(oldFilePath);
currFile.renameTo(new File(newFilePath));
}
private void createZip(String zipFileName) {
ArrayList<File> fileList = listContentsOfZipFile(zipFileName);
renameFile(zipFileName, zipFileName + ".old");
try {
// create byte buffer
byte[] buffer = new byte[1024];
FileOutputStream fos = new FileOutputStream(zipFileName);
ZipOutputStream zos = new ZipOutputStream(fos);
for (File currFile : fileList) {
FileInputStream fis = new FileInputStream(currFile);
// begin writing a new ZIP entry, positions the stream to the start of the entry data
zos.putNextEntry(new ZipEntry(currFile.getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
// close the InputStream
fis.close();
}
// close the ZipOutputStream
zos.close();
} catch (IOException ioe) {
System.out.println("Error creating zip file: " + ioe);
}
}
}