V1_3.java [src/java/m/sci] Revision: 81c3e692916ef0042a55ae22a2b4328bfe8393e3  Date: Wed Sep 02 11:59:41 MDT 2015
/*
 * 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.sci;

import csip.Client;
import csip.ServiceException;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.Callable;
import javax.ws.rs.Path;
import oms3.annotations.Description;
import oms3.annotations.Name;
import oms3.annotations.VersionInfo;
import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import csip.ModelDataService;
import static csip.ModelDataService.ERROR;
import static csip.ModelDataService.FAILED;
import static csip.ModelDataService.KEY_METAINFO;
import static csip.ModelDataService.KEY_STATUS;
import static util.ErosionConst.CONV_KGM2_TONACRE;
import static util.ErosionConst.KEY_LENGTH;
import static util.ErosionConst.KEY_MGMTS;
import static util.ErosionConst.KEY_SCI_ER;
import static util.ErosionConst.KEY_SCI_FO;
import static util.ErosionConst.KEY_SCI_OM;
import static util.ErosionConst.KEY_SCI_VALUE;
import static util.ErosionConst.KEY_SOILS;
import static util.ErosionConst.KEY_STEEPNESS;
import static util.ErosionConst.RES_SLOPE_DEGRAD;
import static util.ErosionConst.RES_SLOPE_DELIVERY;
import static util.ErosionConst.RES_SLOPE_T_VALUE;
import static util.ErosionConst.RES_SOIL_COND_INDEX_ER_SUBFACTOR;
import static util.ErosionConst.RES_SOIL_COND_INDEX_FO_SUBFACTOR;
import static util.ErosionConst.RES_SOIL_COND_INDEX_OM_SUBFACTOR;
import static util.ErosionConst.RES_SOIL_COND_INDEX_RESULT;
import static util.ErosionConst.WEPS_KEY_BARRIERS;
import static util.ErosionConst.WEPS_KEY_MANAGEMENT;
import static util.ErosionConst.WEPS_KEY_SOIL;
import static util.ErosionConst.WEPS_RES_SCI_ER_FACTOR;
import static util.ErosionConst.WEPS_RES_SCI_FO_FACTOR;
import static util.ErosionConst.WEPS_RES_SCI_OM_FACTOR;
import static util.ErosionConst.WEPS_RES_SOIL_COND_INDEX;
import static util.ErosionConst.WEPS_RES_WIND_EROS;
import csip.utils.JSONUtils;
import java.util.Arrays;
import java.util.logging.Logger;
import org.apache.http.HttpHost;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

/**
 *
 * @author User
 */
@Name("SCI")
@Description("IET / Phacil version of SCI")
@VersionInfo("1.3")
@Path("m/sci/1.3.1")
public class V1_3 extends ModelDataService {

    // this is the 0.2 / 2.54 conversion, where 2.54 is ER-renner
    static final Double SCI_CONVERSION_FACTOR = .078740157;
    
    String scitotal = "0.0";
    String sci_om = "0.0";
    String sci_fo = "0.0";
    String sci_er = "0.0";

    @Override
    protected void preprocess() throws Exception {
        // check if sufficient input is there.
        if (!((JSONUtils.checkKeyExistsB(getParamMap(), KEY_SOILS))
                || (JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_SOIL)))) {
            throw new ServiceException("Key not found :SCI SOIL");
        }

        if (!((JSONUtils.checkKeyExistsB(getParamMap(), KEY_MGMTS))
                || (JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_MANAGEMENT)))) {
            throw new ServiceException("Key not found :SCI MANAGEMENT");
        }
    }
    

    @Override
    protected Callable<String> createCallable() throws Exception {
        return new Callable<String>() {

            @Override
            public String call() throws Exception {
                double r2erosion = 0.0;
                double r2sci = 0.0;
                double r2sci_om = 0.0;
                double r2sci_fo = 0.0;
                double r2sci_er = 0.0;

                File[] dummy = new File[0]; // the client function should check for null array.
                JSONObject syncRequest = JSONUtils.clone(getRequest());
                String status;
                String error;
                if (JSONUtils.checkKeyExistsB(getParamMap(), KEY_LENGTH)
                        && JSONUtils.checkKeyExistsB(getParamMap(), KEY_STEEPNESS)) {
                    // do a r2 call >>>
                    JSONArray req_results = new JSONArray();
                    req_results.put(RES_SOIL_COND_INDEX_RESULT);
                    req_results.put(RES_SOIL_COND_INDEX_OM_SUBFACTOR);
                    req_results.put(RES_SOIL_COND_INDEX_FO_SUBFACTOR);
                    req_results.put(RES_SOIL_COND_INDEX_ER_SUBFACTOR);
                    req_results.put(RES_SLOPE_DELIVERY);
                    req_results.put(RES_SLOPE_T_VALUE);
                    req_results.put(RES_SLOPE_DEGRAD);
                    syncRequest.getJSONObject(KEY_METAINFO).put(KEY_MODE, SYNC);
                    syncRequest.getJSONObject(KEY_METAINFO).put(KEY_REQUEST_RESULTS, req_results);
                    //LOG.info("This is the request =) : "+getRequest().toString());
                    //String url = Config.getString("codebase.url", "bad")+"/csip-erosion/m/rusle2/1.2";
                    //LOG.info(url);
                    LOG.info("STARTING RUSLE2");
                    LOG.info("R2 Request" + syncRequest);
                    //JSONObject r2Response = new Client(LOG).doPOST("http://localhost:8080/csip-erosion/m/rusle2/1.2", getRequest(), dummy);
                    JSONObject r2Response = new Client(LOG).doPOST("http://localhost:8080/csip-erosion/m/rusle2/1.3", syncRequest);
                    LOG.info("R2 Response "+ syncRequest);

                    status = r2Response.getJSONObject(KEY_METAINFO).getString(KEY_STATUS);
                    
                    if(status.equals(FAILED)){
                        error = r2Response.getJSONObject(KEY_METAINFO).getString(ERROR);
                        return error;
                    }
                        
                    
                    Map<String, JSONObject> r2Results = JSONUtils.preprocess(r2Response.getJSONArray(KEY_RESULT));

                    r2erosion = Double.parseDouble(r2Results.get(RES_SLOPE_DEGRAD).getString(VALUE));
                    r2sci = Double.parseDouble(r2Results.get(RES_SOIL_COND_INDEX_RESULT).getString(VALUE));
                    r2sci_om = Double.parseDouble(r2Results.get(RES_SOIL_COND_INDEX_OM_SUBFACTOR).getString(VALUE));
                    r2sci_fo = Double.parseDouble(r2Results.get(RES_SOIL_COND_INDEX_FO_SUBFACTOR).getString(VALUE));
                    r2sci_er = Double.parseDouble(r2Results.get(RES_SOIL_COND_INDEX_ER_SUBFACTOR).getString(VALUE));

                    scitotal = Double.toString(r2sci);
                    sci_om = Double.toString(r2sci_om);
                    sci_fo = Double.toString(r2sci_fo);
                    sci_er = Double.toString(r2sci_er);
                }
                // Check if wind barriers (WEPS) tag exists, if so run weps, otherwise return...
                if (!JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_BARRIERS)) {
                    return EXEC_FAILED;
                }
                // only add if the weps soil has not been specified natively
                if (!JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_SOIL)) {
                    LOG.info("There is not soil");
                    JSONObject wepsSoil = new JSONObject();
                    wepsSoil.put("name", WEPS_KEY_SOIL);
                    wepsSoil.put("value", getParamMap().get(KEY_SOILS).getJSONArray("value").get(0));

                    LOG.info("The soil is: " + wepsSoil.toString());
                    //getParamMap().put(WEPS_KEY_SOIL, wepsSoil);
                    syncRequest.getJSONArray(KEY_PARAMETER).put(wepsSoil);
                }
                if (!JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_MANAGEMENT)) {

                    JSONObject lmodweps = (JSONObject) JSONUtils.getJSONArrayParam(getParamMap(), KEY_MGMTS).get(0);
                    JSONObject lmodwepsobj = JSONUtils.data(WEPS_KEY_MANAGEMENT, lmodweps);
                    //getParamMap().put(WEPS_KEY_MANAGEMENT, lmodwepsobj);
                    syncRequest.getJSONArray(KEY_PARAMETER).put(lmodwepsobj);
                }

                LOG.info("Trying to invoke WEPS for SCI");

                //JSONObject wepsResponse = new Client(LOG).doPOST("http://localhost:8080/csip-erosion/m/weps/1.2", getRequest(), dummy);
                JSONObject wepsResponse = new Client(LOG).doPOST("http://localhost:8080/csip-erosion/m/weps/1.3", syncRequest);
                status = wepsResponse.getJSONObject(KEY_METAINFO).getString(KEY_STATUS);
                
                
                if(status.equals(FAILED))
                {
                    error = wepsResponse.getJSONObject(KEY_METAINFO).getString(ERROR);
                    return error;
                }
                
                Map<String, JSONObject> wepsResults = JSONUtils.preprocess(wepsResponse.getJSONArray(KEY_RESULT));

                double wepserosion = (Double.parseDouble(wepsResults.get(WEPS_RES_WIND_EROS).getString(VALUE)));
                    double wepssci = Double.parseDouble(wepsResults.get(WEPS_RES_SOIL_COND_INDEX).getString(VALUE));
                double wepssci_om = Double.parseDouble(wepsResults.get(WEPS_RES_SCI_OM_FACTOR).getString(VALUE));
                double wepssci_fo = Double.parseDouble(wepsResults.get(WEPS_RES_SCI_FO_FACTOR).getString(VALUE));
                double wepssci_er = Double.parseDouble(wepsResults.get(WEPS_RES_SCI_ER_FACTOR).getString(VALUE));

                LOG.info("r2 erosion=" + r2erosion);
                LOG.info("r2 sci=" + r2sci);
                LOG.info("r2 sci_om=" + r2sci_om);
                LOG.info("r2 sci_fo=" + r2sci_fo);
                LOG.info("r2 sci_er=" + r2sci_er);
                LOG.info("weps erosion=" + wepserosion);
                LOG.info("weps sci=" + wepssci);
                LOG.info("weps sci_om=" + wepssci_om);
                LOG.info("weps sci_fo=" + wepssci_fo);
                LOG.info("weps sci_er=" + wepssci_er);

                // if weps only
                if (!((JSONUtils.checkKeyExistsB(getParamMap(), KEY_LENGTH))
                        && (JSONUtils.checkKeyExistsB(getParamMap(), KEY_STEEPNESS)))) {
                    scitotal = Double.toString(wepssci);
                    sci_om = Double.toString(wepssci_om);
                    sci_fo = Double.toString(wepssci_fo);
                    sci_er = Double.toString(wepssci_er);
                    return EXEC_OK;
                }
                if (wepserosion > r2erosion) // if weps wind erosion is more than rusle2 soil erosion
                {
                    scitotal = Double.toString(wepssci - SCI_CONVERSION_FACTOR * r2erosion);
                    sci_er = Double.toString(wepssci_er + r2sci_er - 1);
                    sci_om = Double.toString(wepssci_om);
                    sci_fo = Double.toString(wepssci_fo);
                } else // if rusle2 soil erosion is more than weps wind erosion
                {
                    scitotal = Double.toString(r2sci - SCI_CONVERSION_FACTOR * wepserosion);
                    sci_om = Double.toString(r2sci_om);
                    sci_fo = Double.toString(r2sci_fo);
                    sci_er = Double.toString(wepssci_er + r2sci_er - 1);
                }
                return EXEC_OK;
            }
        };
    }

    @Override
    protected JSONArray createResults() throws Exception {
        JSONArray results = new JSONArray();

        results.put(JSONUtils.dataDesc(KEY_SCI_VALUE, scitotal, "The total SCI value."));
        results.put(JSONUtils.dataDesc(KEY_SCI_OM, sci_om, "The SCI OM (Organic Matter) subfactor. This is 40% of the total SCI value."));
        results.put(JSONUtils.dataDesc(KEY_SCI_FO, sci_fo, "The SCI FO (Field Operations) subfactor.This is 40% of the total SCI value."));
        results.put(JSONUtils.dataDesc(KEY_SCI_ER, sci_er, "The SCI ER (Erosion Rate) subfactor. This is 20% of the total SCI value."));

        return results;
    }

//    @Override
//    protected JSONObject describe() throws JSONException {
//        try {
//            // use this from version 1.1
//            String tmpl = IOUtils.toString(V1_2.class.getResource("/src/m/sci/V1_2Req.json"));
//            JSONObject model = new JSONObject(tmpl);
//            return model;
//        } catch (IOException ex) {
//            throw new RuntimeException("tmpl");
//        }
//    }

    @Override
    protected long getNextPoll() {
        return 1000;
    }

    @Override
    protected long getFirstPoll() {
        return 1000;
    }

}