V1_0.java [src/java/m/weps] Revision: default  Date:
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2017, 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 m.weps;

import csip.Config;
import static csip.Config.CSIP_SESSION_TTL;
import csip.api.server.Executable;
import csip.ModelDataService;
import csip.api.server.ServiceException;
import csip.annotations.*;
import static csip.annotations.ResourceType.*;
import static csip.annotations.State.DEVELOPMENT;
import csip.utils.ZipFiles;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.ws.rs.*;
import static m.wepsModelConstants.PARMOUTMODELNAME;
import static m.wepsModelConstants.PARMOUTUPDATED;

/**
 * This implements the CSIP WEPS service.
 *
 * @author od, mh
 */
@Name("weps for ARS")
@Description("WEPS endpoints for ARS")
@VersionInfo("1.0")
@State(DEVELOPMENT)
@Path("m/weps/1.0")
@Polling(first = 2000, next = 1000)

// ARS versions of the binaries
@Resource(file = "/bin/lin-amd64/ARS/default/2023-01-09/weps", id = "weps-default.lin64", type = EXECUTABLE)
@Resource(file = "/bin/lin-amd64/ARS/dev-version/weps", id = "weps-dev.lin64", type = EXECUTABLE)

//@Resource(file = "*.out *stdout.txt *stderr.txt logfil.txt", type = OUTPUT)
@Resource(file = "*stdout.txt *stderr.txt logfil.txt", type = OUTPUT)

public class V1_0 extends ModelDataService implements Executable.StdHandler {

    Executable weps;
    
    // Reminder: add new date to json as well
    static final String serviceUpdateStr = "05/10/2023";
    
    /**
     *
     * @throws Exception
     */
    @Override
    public void doProcess() throws Exception {
        
        String modelVersion = (parameter().has("modelVersion")) ? parameter().getString("modelVersion") : "";
        
        if (modelVersion.contentEquals("dev-version.lin64")) {
            weps = resources().getExe("weps-dev.lin64");
        } else  if (modelVersion.contentEquals("dev-version")) {
            weps = resources().getExe("weps-dev.lin64");
        } else {
            weps = resources().getExe("weps-default.lin64");
        }

        weps.setStdoutHandler(this);

        String parmHydrologyMethod = "-W" + parameter().getInt("hydrologyMethod", 1);
        String parmResurfacing = "-u" + parameter().getInt("resurfacing", 0);
        String parmInitialization = "-I" + parameter().getInt("initialization", 1);
        String parmConfidenceInterval = "-t" + parameter().getInt("confidenceInterval", 0);
        String parmFurrowEffect = "-T" + parameter().getInt("furrowEffect", 0);
        String parmCalibrationMode = parameter().has("calibrationMode") ? "-C" + parameter().getInt("calibrationMode", 0) : "";
        String parmCalibrationCycles = parameter().has("calibrationCycles") ? "-Z" + parameter().getInt("calibrationCycles", 0) : "";

        weps.setArguments(parmHydrologyMethod,
                parmResurfacing,
                parmInitialization,
                parmConfidenceInterval,
                parmFurrowEffect,
                parmCalibrationMode,
                parmCalibrationCycles,
                "-P" + workspace().getDir()
        );

        int result = weps.exec();
        if (result != 0) {
            throw new ServiceException("WEPS exit error :" + result);
        }
    }


    @Override
    protected void postProcess() throws Exception {
        
        metainfo().put(PARMOUTUPDATED, serviceUpdateStr);
        metainfo().put(PARMOUTMODELNAME, weps.getName());
        metainfo().put("CSIP_SESSION_TTL", Config.getString(CSIP_SESSION_TTL));

        File[] outFiles = workspace().getDir().listFiles( (File file) -> file.getName().endsWith(".out"));
        File[] subRegionFiles = workspace().getDir().listFiles( (File file) -> file.getName().startsWith("subregion"));
        File erodFilesDir = new File(workspace().getDir(),"sae_in_out_files");
        ArrayList<File> zFilesList = new ArrayList();
        
        boolean subRegionResults = (parameter().has("returnSubRegionResults")) ? parameter().getBoolean("returnSubRegionResults") : false;
        boolean zipResults = (parameter().has("zipResults")) ? parameter().getBoolean("zipResults") : false;
        if (zipResults) {
            File zFile = new File(workspace().getDir(),"results.zip");
            
            try {
                if (subRegionResults) {
                    for (File f : subRegionFiles) {
                        File srzFile = new File(workspace().getDir(),f.getName()+".zip");
                        ZipFiles.zip(f,srzFile);
                        zFilesList.add(srzFile);
                    }
                }
            } catch (Exception e) {
            }
            
            try {
                // These files may be triggered by an option in the .runx file
                // instead of as a command line option
                if (erodFilesDir.exists()) {
                    File erzFile = new File(workspace().getDir(),erodFilesDir.getName()+".zip");
                    ZipFiles.zip(erodFilesDir, erzFile);
                    zFilesList.add(erzFile);
                }
            } catch (Exception e) {
            }

            zFilesList.addAll(Arrays.asList(outFiles));
            
            try {
                ZipFiles.zip(zFile, zFilesList);
                results().put(zFile);
            } catch (Exception e) {
            }
        } else {
            results().put(outFiles);
            if (subRegionResults) {
                results().put(subRegionFiles);
            }
            // These files may be triggered by an option in the .runx file
            // instead of as a command line option
            if (erodFilesDir.exists()) {
                results().put(erodFilesDir);
            }
        }
        

        super.postProcess();
    }


    @Override
    public void handle(String out) {
        String s;
        int start;
        int end;
        
        //Subregion            2 Year          12  of          30
        // or
        //Erosion Year           1  of          30

        if ((start = out.lastIndexOf("Year")) >= 0) {
            start = out.lastIndexOf('\n',start)+1;
            if ((end = out.indexOf('\n', start)) == -1) {
                end = out.length();
            }
            if (out.charAt(end - 1) == '\r') {
                end--;
            }
            s = out.substring(start, end);

            try {
                setProgress(s);
            } catch (ServiceException ex) {
                Logger.getLogger(V1_0.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

}