V2_1.java [src/java/d/crlmod/management] Revision: default  Date:
/*
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2024, OMSLab, Colorado State University.
 *
 * OMSLab licenses this file to you under the MIT license.
 * See the LICENSE file in the project root for more information.
 */
package d.crlmod.management;

import crlmod.CRLMODData;
import crlmod.RotationFile;
import crlmod.ServiceResources;
import static crlmod.ServiceResources.*;
import crlmod.utils.Utils;
import csip.Config;
import csip.ModelDataService;
import csip.annotations.*;
import static csip.annotations.State.RELEASED;
import csip.api.server.ServiceException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Path;
import org.apache.commons.lang3.StringUtils;
import rotation_utils.nodes.*;
import rotation_utils.utils.Urls;

@Name("managements")
@Description("Management service for the CRLMOD_2018 Database.  Results from this service are returned in the rotation v2 format.")
@VersionInfo("2.1")
@State(RELEASED)
@Path("d/management/2.1")
@Resource(from = ServiceResources.class)
public class V2_1 extends ModelDataService {

  private final CRLMODData lmodData = new CRLMODData();
  private static final String OBJECT_KEY = "man";
  private static final String OBJECT_NAME = "Management";

  protected String opUrlKey = "crlmod21.op";
  protected String crUrlKey = "crlmod21.crop";
  protected String reUrlKey = "crlmod21.residue";
  // TODO: why 4.1?
  protected String verKey = "4.1"; 
  protected String jdbcId = "CR_LMOD_2018_ID";

  @Override
  protected void doProcess() throws Exception {
    boolean nativeFormats = parameter().getBoolean(KEY_NATIVEFORMATS, false);
    getManagements();
    if (nativeFormats)
      getNativeFormats(lmodData);
  }

  protected void getNativeFormats(CRLMODData lmodData) throws Exception {
    Urls urls = new Urls();
    urls.setOperations(getOpURL());
    urls.setCrops(getCrURL());
    urls.setResidue(getReURL());

    for (int rotIdx = 0; rotIdx < lmodData.rotationFiles.size(); rotIdx++) {
      String wepsData = lmodData.rotationFiles.get(rotIdx).rotation.translateToWEPSString(workspace().getDir().toString(), urls);
      lmodData.rotationFiles.get(rotIdx).wepsData = wepsData;
    }
  }

  protected Connection getConnection() throws ServiceException {
    return resources().getJDBC(CR_LMOD_2018_ID);
  }

  public void getManagements() throws Exception {
    List<String> params = new ArrayList<>();
    String countQuery = "SELECT COUNT(*) as Count FROM managements\n";
    countQuery += Utils.createWhere(params, OBJECT_KEY, OBJECT_NAME, parameter(), LOG);

    String query = "SELECT "
        + "    sub.man_id, sub.man_name, sub.man_path, sub.man_duration, sub.man_stir, \n"
        + "    events.date, events.res_amount, \n"
        + "    op_id, op_name, op_group1, op_group2, op_group3, op_group4, op_group5, "
        + "    op_begin_growth, op_kill_crop, op_add_residue, op_stir, op_res_added, \n"
        + "    crop_id, crop_name, crop_group1, crop_group2, crop_group3, crop_group4, crop_group5,"
        + "    crop_yield, crop_yield_unit, \n"
        + "    res_id, res_name, res_group1, res_group2, res_group3, res_group4, res_group5\n"
        + "FROM   "
        + "   (SELECT man_id, man_name, man_path, man_duration, man_stir FROM managements\n"
        + Utils.createWhere(params, OBJECT_KEY, OBJECT_NAME, parameter(), LOG) + "\n"
        + Utils.createOffsetAndLimits(params, parameter(), LOG, OBJECT_NAME, OBJECT_KEY)
        + "    )sub\n"
        + "    left join events on man_id = fk_man_id\n"
        + "    left join crops on events.fk_crop_id = crops.crop_id\n"
        + "    left join operations on events.fk_op_id = operations.op_id\n"
        + "    left join residues on events.fk_res_id = residues.res_id\n";
    query += "ORDER BY sub.man_id, event_index";

    try (Connection con = resources().getJDBC(jdbcId)) {
      try (Statement statement = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
        try (ResultSet resultSet = statement.executeQuery(countQuery)) {
          resultSet.next();
          lmodData.rotationFileCount = resultSet.getInt("Count");
        }

        try (ResultSet resultSet = statement.executeQuery(query)) {
          Rotation rot = new Rotation();
          Management man = new Management();
          rot.managements.add(man);

          while (resultSet.next()) {
            Event event = new Event();

            rot.duration = resultSet.getInt("man_duration");
            event.date = resultSet.getDate("date").toLocalDate();

            Operation operation = new Operation();
            operation.id = resultSet.getBigDecimal("op_id").toPlainString();
            operation.name = resultSet.getString("op_name");
            operation.opGroup1 = resultSet.getString("op_group1") == null ? "" : resultSet.getString("op_group1");
            operation.opGroup2 = resultSet.getString("op_group2") == null ? "" : resultSet.getString("op_group2");
            operation.opGroup3 = resultSet.getString("op_group3") == null ? "" : resultSet.getString("op_group3");
            operation.opGroup4 = resultSet.getString("op_group4") == null ? "" : resultSet.getString("op_group4");
            operation.opGroup5 = resultSet.getString("op_group5") == null ? "" : resultSet.getString("op_group5");
            operation.stir = resultSet.getDouble("op_stir");
            operation.add_residue = resultSet.getBoolean("op_add_residue");
            operation.begin_growth = resultSet.getBoolean("op_begin_growth");
            operation.kill_crop = resultSet.getBoolean("op_kill_crop");
            operation.defaultResidueAdded = resultSet.getDouble("op_res_added");
            event.operation = operation;

            if (!StringUtils.isEmpty(resultSet.getString("crop_name"))) {
              Crop crop = new Crop();
              crop.id = resultSet.getBigDecimal("crop_id").toPlainString();
              crop.name = resultSet.getString("crop_name");
              crop.cropGroup1 = resultSet.getString("crop_group1");
              crop.cropGroup2 = resultSet.getString("crop_group2");
              crop.cropGroup3 = resultSet.getString("crop_group3");
              crop.cropGroup4 = resultSet.getString("crop_group4");
              crop.cropGroup5 = resultSet.getString("crop_group5");
              crop.defaultYield = resultSet.getDouble("crop_yield");
              crop.yieldUnit = resultSet.getString("crop_yield_unit");
              event.crop = crop;
              event.crop.yield = crop.defaultYield;
            }

            if (!StringUtils.isEmpty(resultSet.getString("res_name"))) {
              Residue res = new Residue();
              res.id = resultSet.getBigDecimal("res_id").toPlainString();
              res.name = resultSet.getString("res_name");
              res.resGroup1 = resultSet.getString("res_group1");
              res.resGroup2 = resultSet.getString("res_group2");
              res.resGroup3 = resultSet.getString("res_group3");
              res.resGroup4 = resultSet.getString("res_group4");
              res.resGroup5 = resultSet.getString("res_group5");
              res.res_added = resultSet.getDouble("res_amount");

              event.residue = res;
            }

            if (man.id == null) {
              man.id = resultSet.getBigDecimal("man_id").toPlainString();
              man.name = resultSet.getString("man_name");
              man.path = resultSet.getString("man_path");
              man.stir = resultSet.getDouble("man_stir");
            }

            if (!man.id.equals(resultSet.getBigDecimal("man_id").toPlainString())) {
              lmodData.addRotation(rot);
              rot = new Rotation();
              man = new Management(resultSet.getBigDecimal("man_id").toPlainString());
              man.name = resultSet.getString("man_name");
              man.path = resultSet.getString("man_path");
              man.stir = resultSet.getDouble("man_stir");
              rot.managements.add(man);
            }
            man.events.add(event);
          }

          //No need to include 'empty' managements.
          if (rot.managements.get(0).events.size() != 0)
            lmodData.addRotation(rot);
          if (lmodData.rotationFileCount == 0)
            throw new ServiceException("No managements match your search criteria");
        } catch (Exception ex) {
          throw new ServiceException(ex);
        }
      }
    }
  }

  @Override
  protected void postProcess() throws Exception {
    if (parameter().getBoolean(KEY_NAMESONLY, false)) {
      for (RotationFile rFile : lmodData.rotationFiles) {
        Rotation rot = rFile.rotation;
        rot.managements.get(0).events = null;
        rot.duration = null;
      }
    }
    results().put("crlmod", lmodData.getJson());
  }

  private String getOpURL() {
    return Config.getString(opUrlKey, "http://csip.engr.colostate.edu:8092/csip-crlmod/d/operation/" + verKey);
  }

  private String getCrURL() {
    return Config.getString(crUrlKey, "http://csip.engr.colostate.edu:8092/csip-crlmod/d/crop/" + verKey);
  }

  private String getReURL() {
    return Config.getString(reUrlKey, "http://csip.engr.colostate.edu:8092/csip-crlmod/d/residue/" + verKey);
  }

  @Override
  protected Map<String, Object> getConfigInfo() {
    return new LinkedHashMap<String, Object>() {
      {
        put(jdbcId, resources().getResolved(jdbcId));
        put(opUrlKey, getOpURL());
        put(crUrlKey, getCrURL());
        put(reUrlKey, getReURL());
      }
    };
  }
}