From cbf1e3eaa1bc42ff6b03a35d55e674cff8d6df0e Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Tue, 17 Jun 2025 14:26:00 -0400 Subject: [PATCH 01/65] SQL Table in progress --- .../src/main/resources/scripts/init.sql | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index f338f9d49a..0c6b0b472e 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -77,6 +77,41 @@ CREATE TABLE vc_metadata(id bigint PRIMARY KEY,bioModelRef bigint NOT NULL REFER CREATE TABLE vc_simdelfromdisk(deldate varchar(20) ,userid varchar(255) NOT NULL,userkey bigint ,simid bigint ,simpref bigint ,simdate varchar(20) ,simname varchar(255) NOT NULL,status varchar(10) ,numfiles bigint ,totalsize bigint ); CREATE TABLE vc_useridentity(id bigint PRIMARY KEY,userRef bigint NOT NULL REFERENCES vc_userinfo(id),authSubject varchar(128) NOT NULL,authIssuer varchar(128) NOT NULL,insertDate timestamp NOT NULL); +CREATE TABLE vc_model_export_history ( + id bigint PRIMARY KEY, + job_id bigint NOT NULL, + user_ref bigint NOT NULL REFERENCES vc_userinfo(id) ON DELETE CASCADE, + model_ref bigint REFERENCES vc_model(id) ON DELETE CASCADE, + export_format varchar(50) NOT NULL, + export_date timestamp NOT NULL, + uri text NOT NULL, + data_id varchar(255) NOT NULL, + simulation_name varchar(255) NOT NULL, + application_name varchar(255) NOT NULL, + biomodel_name varchar(255) NOT NULL REFERENCES vc_model(name) ON DELETE CASCADE, + variables text[] NOT NULL, + start_time numeric NOT NULL, + end_time numeric NOT NULL, +-- different_parameter_values text[] NOT NULL DEFAULT '{}'::text[], + saved_file_name varchar(255) DEFAULT NULL, + application_type varchar(50) NOT NULL, + non_spatial boolean NOT NULL, + z_slices integer NOT NULL, + t_slices integer NOT NULL, + num_variables integer NOT NULL, + insert_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE vc_model_parameter_values( + export_id bigint PRIMARY KEY NOT NULL REFERENCES vc_model_export_history(id), + user_ref bigint NOT NULL REFERENCES vc_userinfo(id) ON DELETE CASCADE, + model_ref bigint REFERENCES vc_model(id) ON DELETE CASCADE, + parameter_name text NOT NULL, + parameter_original numeric NOT NULL, + parameter_changed numeric NOT NULL, +); + + CREATE VIEW public.dual AS SELECT CAST('X' as varchar) AS dummy; CREATE SEQUENCE newSeq; From fd034f80212c5aa5dec8c19f165600ed9e193b21 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Wed, 18 Jun 2025 12:51:17 -0400 Subject: [PATCH 02/65] Fixed reference error --- vcell-rest/src/main/resources/scripts/init.sql | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 0c6b0b472e..7fad3ac464 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -80,7 +80,7 @@ CREATE TABLE vc_useridentity(id bigint PRIMARY KEY,userRef bigint NOT NULL REFER CREATE TABLE vc_model_export_history ( id bigint PRIMARY KEY, job_id bigint NOT NULL, - user_ref bigint NOT NULL REFERENCES vc_userinfo(id) ON DELETE CASCADE, + user_ref bigint REFERENCES vc_userinfo(id) ON DELETE CASCADE, model_ref bigint REFERENCES vc_model(id) ON DELETE CASCADE, export_format varchar(50) NOT NULL, export_date timestamp NOT NULL, @@ -88,27 +88,27 @@ CREATE TABLE vc_model_export_history ( data_id varchar(255) NOT NULL, simulation_name varchar(255) NOT NULL, application_name varchar(255) NOT NULL, - biomodel_name varchar(255) NOT NULL REFERENCES vc_model(name) ON DELETE CASCADE, + biomodel_name varchar(255) REFERENCES vc_model(name) ON DELETE CASCADE, variables text[] NOT NULL, start_time numeric NOT NULL, end_time numeric NOT NULL, -- different_parameter_values text[] NOT NULL DEFAULT '{}'::text[], - saved_file_name varchar(255) DEFAULT NULL, + saved_file_name varchar(255) NOT NULL, application_type varchar(50) NOT NULL, non_spatial boolean NOT NULL, - z_slices integer NOT NULL, - t_slices integer NOT NULL, - num_variables integer NOT NULL, + z_slices integer NOT NULL DEFAULT 0, + t_slices integer NOT NULL DEFAULT 0, + num_variables integer NOT NULL DEFAULT 0, insert_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE vc_model_parameter_values( - export_id bigint PRIMARY KEY NOT NULL REFERENCES vc_model_export_history(id), - user_ref bigint NOT NULL REFERENCES vc_userinfo(id) ON DELETE CASCADE, + export_id bigint PRIMARY KEY REFERENCES vc_model_export_history(id), + user_ref bigint REFERENCES vc_userinfo(id) ON DELETE CASCADE, model_ref bigint REFERENCES vc_model(id) ON DELETE CASCADE, parameter_name text NOT NULL, parameter_original numeric NOT NULL, - parameter_changed numeric NOT NULL, + parameter_changed numeric NOT NULL ); From ec842378da2bf5ea9e274d4dbedf345494d15a9d Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Fri, 20 Jun 2025 09:38:37 -0400 Subject: [PATCH 03/65] Fixed sql key error --- vcell-rest/src/main/resources/scripts/init.sql | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 7fad3ac464..528a991dc9 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -80,15 +80,15 @@ CREATE TABLE vc_useridentity(id bigint PRIMARY KEY,userRef bigint NOT NULL REFER CREATE TABLE vc_model_export_history ( id bigint PRIMARY KEY, job_id bigint NOT NULL, - user_ref bigint REFERENCES vc_userinfo(id) ON DELETE CASCADE, - model_ref bigint REFERENCES vc_model(id) ON DELETE CASCADE, + user_ref bigint NOT NULL REFERENCES vc_userinfo(id) ON DELETE CASCADE, + model_ref bigint NOT NULL REFERENCES vc_model(id) ON DELETE CASCADE, export_format varchar(50) NOT NULL, export_date timestamp NOT NULL, uri text NOT NULL, data_id varchar(255) NOT NULL, simulation_name varchar(255) NOT NULL, application_name varchar(255) NOT NULL, - biomodel_name varchar(255) REFERENCES vc_model(name) ON DELETE CASCADE, + biomodel_name varchar(255) NOT NULL, variables text[] NOT NULL, start_time numeric NOT NULL, end_time numeric NOT NULL, @@ -98,12 +98,11 @@ CREATE TABLE vc_model_export_history ( non_spatial boolean NOT NULL, z_slices integer NOT NULL DEFAULT 0, t_slices integer NOT NULL DEFAULT 0, - num_variables integer NOT NULL DEFAULT 0, - insert_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP + num_variables integer NOT NULL DEFAULT 0 ); CREATE TABLE vc_model_parameter_values( - export_id bigint PRIMARY KEY REFERENCES vc_model_export_history(id), + id bigint PRIMARY KEY REFERENCES vc_model_export_history(id), user_ref bigint REFERENCES vc_userinfo(id) ON DELETE CASCADE, model_ref bigint REFERENCES vc_model(id) ON DELETE CASCADE, parameter_name text NOT NULL, @@ -122,6 +121,9 @@ CREATE INDEX geom_extentref ON vc_geometry(extentRef); CREATE INDEX geom_imageref ON vc_geometry(imageRef); CREATE INDEX mathdesc_geomref ON vc_math(geometryRef); CREATE INDEX simcstat_simcref ON vc_simcontextstat(simContextRef); +CREATE INDEX idx_export_history_model_ref ON vc_model_export_history(model_ref); +CREATE INDEX idx_param_values_id ON vc_model_parameter_values(id); + INSERT INTO vc_userinfo VALUES ( 0,'void','1700596370242','void@example.com','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'B9BDD75BC5382CA83D5AB82172A98D869555899C' ); INSERT INTO vc_userinfo VALUES ( 2,'Administrator','1700596370260','Administrator@example.com','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'CD181552B879A2F29D10434D8ACF692B6C8126F9' ); From fcee9908f6d071bb0ea3ffe7cf407ef9268c65f1 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Fri, 20 Jun 2025 11:46:19 -0400 Subject: [PATCH 04/65] Added exportation to database script --- .../vcell/client/data/PDEExportDataPanel.java | 93 +++++++++++- .../export/server/ExportServiceImpl.java | 137 ++++++++++++++++++ .../cbit/vcell/export/server/ExportSpecs.java | 92 ++++++++++++ 3 files changed, 321 insertions(+), 1 deletion(-) diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java index 5b2a2dd4c3..afe5edf663 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java @@ -45,8 +45,10 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.math.BigDecimal; import java.net.URL; import java.nio.channels.FileChannel; +import java.sql.*; import java.util.*; /** * This type was created in VisualAge. @@ -704,7 +706,96 @@ private ExportSpecs getExportSpecs() { return exportSpecs; } -private ExportSpecs.SimulationSelector createSimulationSelector(){ +private void saveExportToDatabase( + //long iD, + ExportEvent exportEvent, + ExportSpecs exportSpecs, + long userRef, + long modelRef +) throws SQLException { + + final String INSERT_HISTORY = + "INSERT INTO vc_model_export_history (" + + " id, job_id, user_ref, model_ref, export_format, export_date, uri," + + " data_id, simulation_name, application_name, biomodel_name, variables," + + " start_time, end_time, saved_file_name, application_type, non_spatial," + + " z_slices, t_slices, num_variables" + + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + final String INSERT_PARAM = + "INSERT INTO vc_model_parameter_values (" + + " export_id, user_ref, model_ref, parameter_name," + + " parameter_original, parameter_changed" + + ") VALUES (?,?,?,?,?,?)"; + + try (Connection conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); + PreparedStatement psHist = conn.prepareStatement(INSERT_HISTORY); + PreparedStatement psParam = conn.prepareStatement(INSERT_PARAM)) { + + + HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); + TimeSpecs tm = exportSpecs.getTimeSpecs(); + + // 1) vc_model_export_history + //psHist.setLong (1, iD); + psHist.setLong (2, exportEvent.getJobID()); + psHist.setLong (3, userRef); + psHist.setLong (4, modelRef); + psHist.setString (5, exportSpecs.getFormat().name()); + psHist.setTimestamp (6, new Timestamp(System.currentTimeMillis())); + psHist.setString (7, exportEvent.getLocation()); + psHist.setString (8, exportSpecs.getVCDataIdentifier().toString()); + psHist.setString (9, meta.simulationName); + psHist.setString (10, meta.applicationName); + psHist.setString (11, meta.biomodelName); + + // variables → SQL text[] + String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); + Array sqlVars = conn.createArrayOf("text", vars); + psHist.setArray (12, sqlVars); + + // start/end time + String timeRange = tm.toString(); + String[] time_parts = timeRange.split("/"); + BigDecimal start = new BigDecimal(time_parts[0]); + BigDecimal end = new BigDecimal(time_parts[1]); + + + psHist.setBigDecimal (13, start); + psHist.setBigDecimal (14, end); + + psHist.setString (15, meta.serverSavedFileName); + + psHist.setString (15, meta.serverSavedFileName); + psHist.setString (16, meta.applicationType); + psHist.setBoolean (17, meta.nonSpatial); + psHist.setInt (18, meta.zSlices); + psHist.setInt (19, meta.tSlices); + psHist.setInt (20, meta.numChannels); + + psHist.executeUpdate(); + + + for (String entry : meta.differentParameterValues) { + + String[] param_parts = entry.split(","); + if (param_parts.length == 3) { + //psParam.setLong (1, iD); + psParam.setLong (2, userRef); + psParam.setLong (3, modelRef); + psParam.setString (4, (param_parts[0])); + psParam.setBigDecimal (5, new BigDecimal(param_parts[1])); + psParam.setBigDecimal (6, new BigDecimal(param_parts[2])); + psParam.addBatch(); + } + } + psParam.executeBatch(); + } +} + + + + private ExportSpecs.SimulationSelector createSimulationSelector(){ ExportSpecs.SimulationSelector simulationSelector = new ExportSpecs.SimulationSelector(){ diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java index b9c0957871..2b35829ae6 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java @@ -15,8 +15,10 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.math.BigDecimal; import java.net.MalformedURLException; import java.net.URL; +import java.sql.*; import java.util.Collection; import java.util.zip.DataFormatException; import java.util.zip.ZipEntry; @@ -60,6 +62,49 @@ public ExportEvent makeRemoteFile(OutputContext outputContext,User user, DataSer return makeRemoteFile(outputContext,user, dataServerImpl, exportSpecs, eventController, JobRequest.createExportJobRequest(user).getExportJobID()); } + +/** + * Insert the method's description here. + * Creation date: (4/1/2001 11:20:45 AM) + * @deprecated + */ +protected ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, String format, String location,ExportSpecs exportSpecs) { + User user = null; + Object object = jobRequestIDs.get(new Long(jobID)); + if (object != null) { + user = (User)object; + } + TimeSpecs timeSpecs = (exportSpecs!=null)?exportSpecs.getTimeSpecs():(null); + VariableSpecs varSpecs = (exportSpecs!=null)?exportSpecs.getVariableSpecs():(null); + final KeyValue dataKey; + if (vcdID instanceof VCSimulationDataIdentifier) { + dataKey = ((VCSimulationDataIdentifier)vcdID).getSimulationKey(); + }else if (vcdID instanceof ExternalDataIdentifier) { + dataKey = ((ExternalDataIdentifier)vcdID).getSimulationKey(); + }else { + throw new RuntimeException("unexpected VCDataIdentifier"); + } + ExportEvent event = new ExportEvent( + this, jobID, user, vcdID.getID(), dataKey, ExportEvent.EXPORT_COMPLETE, + format, location, null, timeSpecs, varSpecs); + event.setHumanReadableExportData(exportSpecs != null ? exportSpecs.getHumanReadableExportData() : null); + + assert exportSpecs != null; + event.setHumanReadableExportData(exportSpecs.getHumanReadableExportData()); + assert user != null; + + +exportToDb( + jobID, + Long.parseLong(user.getID().toString()), + Long.parseLong(vcdID.getOwner().getID().toString()), + format, + new Timestamp(System.currentTimeMillis()), + location, + exportSpecs + ); + fireExportEvent(event); + return event; public ExportEvent makeRemoteFile(OutputContext outputContext, User user, DataServerImpl dataServer, ExportSpecs exportSpecs, boolean zip, ClientTaskStatusSupport clientTaskStatusSupport)throws DataAccessException { return makeRemoteFile(outputContext, user, dataServer, exportSpecs, eventController, zip, clientTaskStatusSupport, JobRequest.createExportJobRequest(user).getExportJobID()); } @@ -349,4 +394,96 @@ private static ExportEvent makeRemoteN5File(String fileFormat, String fileName, } } +} + +private void exportToDb(long jobID, + long userRef, + long modelRef, + String exportFormat, + Timestamp exportDate, + String uri, + ExportSpecs exportSpecs) { + Connection conn = null; + PreparedStatement ps = null; + PreparedStatement psParam = null; + ResultSet rsSeq = null; + try { + conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); + + // 1) history ID already passed in (jobID), skip sequence + + // 2) Insert into vc_model_export_history + String hsql = + "INSERT INTO vc_model_export_history (" + + "id, job_id, user_ref, model_ref, export_format, export_date, uri," + + "data_id, simulation_name, application_name, biomodel_name, variables," + + "start_time, end_time, saved_file_name, application_type, non_spatial," + + "z_slices, t_slices, num_variables" + + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + ps = conn.prepareStatement(hsql); + + HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); + TimeSpecs ts = exportSpecs.getTimeSpecs(); + String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); + + String timeRange = ts.toString(); + String[] time_parts = timeRange.split("/"); + BigDecimal startTime = new BigDecimal(time_parts[0]); + BigDecimal endTime = new BigDecimal(time_parts[1]); + + //ps.setLong (1, historyId); + ps.setLong (2, jobID); // job_id == id + ps.setLong (3, userRef); + ps.setLong (4, modelRef); + ps.setString (5, exportFormat); + ps.setTimestamp (6, exportDate); + ps.setString (7, uri); + ps.setString (8, exportSpecs.getVCDataIdentifier().getID()); + ps.setString (9, meta.simulationName); + ps.setString (10, meta.applicationName); + ps.setString (11, meta.biomodelName); + ps.setArray (12, conn.createArrayOf("text", vars)); + ps.setBigDecimal (13, startTime); + ps.setBigDecimal (14, endTime); + ps.setString (15, meta.serverSavedFileName); + ps.setString (16, meta.applicationType); + ps.setBoolean (17, meta.nonSpatial); + ps.setInt (18, meta.zSlices); + ps.setInt (19, meta.tSlices); + ps.setInt (20, meta.numChannels); + ps.executeUpdate(); + + // 3) parameter values + String psql = + "INSERT INTO vc_model_parameter_values (" + + "export_id, user_ref, model_ref, parameter_name," + + "parameter_original, parameter_changed" + + ") VALUES (?,?,?,?,?,?)"; + psParam = conn.prepareStatement(psql); + for (String entry : meta.differentParameterValues) { + String[] parts = entry.split(":"); + if (parts.length == 3) { + //psParam.setLong (1, historyId); + psParam.setLong (2, userRef); + psParam.setLong (3, modelRef); + psParam.setString (4, parts[0]); + psParam.setBigDecimal (5, new BigDecimal(parts[1])); + psParam.setBigDecimal (6, new BigDecimal(parts[2])); + psParam.addBatch(); + } + } + psParam.executeBatch(); + } + catch(SQLException e){ + lg.error("Error persisting export",e); + } + finally { + try{ if(rsSeq !=null) rsSeq.close(); }catch(Exception ign){} + try{ if(psParam !=null) psParam.close(); }catch(Exception ign){} + try{ if(ps !=null) ps.close(); }catch(Exception ign){} + try{ if(conn !=null) conn.close(); }catch(Exception ign){} + } +} + + } diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java index 352036a95d..890324e096 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java @@ -208,4 +208,96 @@ public void setExportMetaData(HumanReadableExportData humanReadableExportData){ public HumanReadableExportData getHumanReadableExportData(){ return humanReadableExportData; } + + +private void saveExportToDatabase( + //long iD, + ExportEvent exportEvent, + ExportSpecs exportSpecs, + long userRef, + long modelRef +) throws SQLException { + + final String INSERT_HISTORY = + "INSERT INTO vc_model_export_history (" + + " id, job_id, user_ref, model_ref, export_format, export_date, uri," + + " data_id, simulation_name, application_name, biomodel_name, variables," + + " start_time, end_time, saved_file_name, application_type, non_spatial," + + " z_slices, t_slices, num_variables" + + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + final String INSERT_PARAM = + "INSERT INTO vc_model_parameter_values (" + + " export_id, user_ref, model_ref, parameter_name," + + " parameter_original, parameter_changed" + + ") VALUES (?,?,?,?,?,?)"; + + try (Connection conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); + PreparedStatement psHist = conn.prepareStatement(INSERT_HISTORY); + PreparedStatement psParam = conn.prepareStatement(INSERT_PARAM)) { + + + HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); + TimeSpecs tm = exportSpecs.getTimeSpecs(); + + // 1) vc_model_export_history + //psHist.setLong (1, iD); + psHist.setLong (2, exportEvent.getJobID()); + psHist.setLong (3, userRef); + psHist.setLong (4, modelRef); + psHist.setString (5, exportSpecs.getFormat().name()); + psHist.setTimestamp (6, new Timestamp(System.currentTimeMillis())); + psHist.setString (7, exportEvent.getLocation()); + psHist.setString (8, exportSpecs.getVCDataIdentifier().toString()); + psHist.setString (9, exportSpecs.getSimulationName()); + psHist.setString (10, meta.applicationName); + psHist.setString (11, meta.biomodelName); + + // variables → SQL text[] + String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); + Array sqlVars = conn.createArrayOf("text", vars); + psHist.setArray (12, sqlVars); + + // start/end time + String timeRange = tm.toString(); + String[] time_parts = timeRange.split("/"); + BigDecimal start = new BigDecimal(time_parts[0]); + BigDecimal end = new BigDecimal(time_parts[1]); + + + psHist.setBigDecimal (13, start); + psHist.setBigDecimal (14, end); + + psHist.setString (15, meta.serverSavedFileName); + + psHist.setString (15, meta.serverSavedFileName); + psHist.setString (16, meta.applicationType); + psHist.setBoolean (17, meta.nonSpatial); + psHist.setInt (18, meta.zSlices); + psHist.setInt (19, meta.tSlices); + psHist.setInt (20, meta.numChannels); + + psHist.executeUpdate(); + + + for (String entry : meta.differentParameterValues) { + + String[] param_parts = entry.split(","); + if (param_parts.length == 3) { + //psParam.setLong (1, iD); + psParam.setLong (2, userRef); + psParam.setLong (3, modelRef); + psParam.setString (4, (param_parts[0])); + psParam.setBigDecimal (5, new BigDecimal(param_parts[1])); + psParam.setBigDecimal (6, new BigDecimal(param_parts[2])); + psParam.addBatch(); + } + } + psParam.executeBatch(); + } +} + + + + } From cb1b0e9e47a9d81ac7e28aeddfafae39930bea91 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Fri, 20 Jun 2025 11:47:59 -0400 Subject: [PATCH 05/65] Removed client side insert db script --- .../vcell/client/data/PDEExportDataPanel.java | 87 +------------------ 1 file changed, 1 insertion(+), 86 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java index afe5edf663..c30a30e102 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java @@ -706,92 +706,7 @@ private ExportSpecs getExportSpecs() { return exportSpecs; } -private void saveExportToDatabase( - //long iD, - ExportEvent exportEvent, - ExportSpecs exportSpecs, - long userRef, - long modelRef -) throws SQLException { - - final String INSERT_HISTORY = - "INSERT INTO vc_model_export_history (" + - " id, job_id, user_ref, model_ref, export_format, export_date, uri," + - " data_id, simulation_name, application_name, biomodel_name, variables," + - " start_time, end_time, saved_file_name, application_type, non_spatial," + - " z_slices, t_slices, num_variables" + - ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; - - final String INSERT_PARAM = - "INSERT INTO vc_model_parameter_values (" + - " export_id, user_ref, model_ref, parameter_name," + - " parameter_original, parameter_changed" + - ") VALUES (?,?,?,?,?,?)"; - - try (Connection conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); - PreparedStatement psHist = conn.prepareStatement(INSERT_HISTORY); - PreparedStatement psParam = conn.prepareStatement(INSERT_PARAM)) { - - - HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); - TimeSpecs tm = exportSpecs.getTimeSpecs(); - - // 1) vc_model_export_history - //psHist.setLong (1, iD); - psHist.setLong (2, exportEvent.getJobID()); - psHist.setLong (3, userRef); - psHist.setLong (4, modelRef); - psHist.setString (5, exportSpecs.getFormat().name()); - psHist.setTimestamp (6, new Timestamp(System.currentTimeMillis())); - psHist.setString (7, exportEvent.getLocation()); - psHist.setString (8, exportSpecs.getVCDataIdentifier().toString()); - psHist.setString (9, meta.simulationName); - psHist.setString (10, meta.applicationName); - psHist.setString (11, meta.biomodelName); - - // variables → SQL text[] - String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); - Array sqlVars = conn.createArrayOf("text", vars); - psHist.setArray (12, sqlVars); - - // start/end time - String timeRange = tm.toString(); - String[] time_parts = timeRange.split("/"); - BigDecimal start = new BigDecimal(time_parts[0]); - BigDecimal end = new BigDecimal(time_parts[1]); - - - psHist.setBigDecimal (13, start); - psHist.setBigDecimal (14, end); - - psHist.setString (15, meta.serverSavedFileName); - - psHist.setString (15, meta.serverSavedFileName); - psHist.setString (16, meta.applicationType); - psHist.setBoolean (17, meta.nonSpatial); - psHist.setInt (18, meta.zSlices); - psHist.setInt (19, meta.tSlices); - psHist.setInt (20, meta.numChannels); - - psHist.executeUpdate(); - - - for (String entry : meta.differentParameterValues) { - - String[] param_parts = entry.split(","); - if (param_parts.length == 3) { - //psParam.setLong (1, iD); - psParam.setLong (2, userRef); - psParam.setLong (3, modelRef); - psParam.setString (4, (param_parts[0])); - psParam.setBigDecimal (5, new BigDecimal(param_parts[1])); - psParam.setBigDecimal (6, new BigDecimal(param_parts[2])); - psParam.addBatch(); - } - } - psParam.executeBatch(); - } -} + From 205300089d026524a7043a27a92b52bc5bcc90d1 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:27:17 -0400 Subject: [PATCH 06/65] Refactoring sql syntax --- .../export/server/ExportServiceImpl.java | 25 ++++++++++--------- .../cbit/vcell/export/server/ExportSpecs.java | 1 - .../src/main/resources/scripts/init.sql | 1 - 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java index 2b35829ae6..48ab8ed5c4 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java @@ -94,7 +94,7 @@ protected ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, St assert user != null; -exportToDb( +exportToDB( jobID, Long.parseLong(user.getID().toString()), Long.parseLong(vcdID.getOwner().getID().toString()), @@ -396,7 +396,7 @@ private static ExportEvent makeRemoteN5File(String fileFormat, String fileName, } -private void exportToDb(long jobID, +private void exportToDB(long jobID, long userRef, long modelRef, String exportFormat, @@ -407,20 +407,19 @@ private void exportToDb(long jobID, PreparedStatement ps = null; PreparedStatement psParam = null; ResultSet rsSeq = null; + boolean passed; try { conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); - // 1) history ID already passed in (jobID), skip sequence - // 2) Insert into vc_model_export_history - String hsql = + String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server "INSERT INTO vc_model_export_history (" + "id, job_id, user_ref, model_ref, export_format, export_date, uri," + "data_id, simulation_name, application_name, biomodel_name, variables," + "start_time, end_time, saved_file_name, application_type, non_spatial," + "z_slices, t_slices, num_variables" + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; - ps = conn.prepareStatement(hsql); + ps = conn.prepareStatement(vcmExpHiSQL); HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); TimeSpecs ts = exportSpecs.getTimeSpecs(); @@ -431,8 +430,8 @@ private void exportToDb(long jobID, BigDecimal startTime = new BigDecimal(time_parts[0]); BigDecimal endTime = new BigDecimal(time_parts[1]); - //ps.setLong (1, historyId); - ps.setLong (2, jobID); // job_id == id + + ps.setLong (2, jobID); ps.setLong (3, userRef); ps.setLong (4, modelRef); ps.setString (5, exportFormat); @@ -453,13 +452,15 @@ private void exportToDb(long jobID, ps.setInt (20, meta.numChannels); ps.executeUpdate(); - // 3) parameter values - String psql = + + String vcmExpHisPVSQL = // SQL statement for inserting into vc_model_parameter_value table in VCell server "INSERT INTO vc_model_parameter_values (" + "export_id, user_ref, model_ref, parameter_name," + "parameter_original, parameter_changed" + ") VALUES (?,?,?,?,?,?)"; - psParam = conn.prepareStatement(psql); + psParam = conn.prepareStatement(vcmExpHisPVSQL); + + for (String entry : meta.differentParameterValues) { String[] parts = entry.split(":"); if (parts.length == 3) { @@ -475,7 +476,7 @@ private void exportToDb(long jobID, psParam.executeBatch(); } catch(SQLException e){ - lg.error("Error persisting export",e); + lg.error("Error exporting to database",e); } finally { try{ if(rsSeq !=null) rsSeq.close(); }catch(Exception ign){} diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java index 890324e096..71fc18b28d 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java @@ -211,7 +211,6 @@ public HumanReadableExportData getHumanReadableExportData(){ private void saveExportToDatabase( - //long iD, ExportEvent exportEvent, ExportSpecs exportSpecs, long userRef, diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 528a991dc9..aca585687a 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -92,7 +92,6 @@ CREATE TABLE vc_model_export_history ( variables text[] NOT NULL, start_time numeric NOT NULL, end_time numeric NOT NULL, --- different_parameter_values text[] NOT NULL DEFAULT '{}'::text[], saved_file_name varchar(255) NOT NULL, application_type varchar(50) NOT NULL, non_spatial boolean NOT NULL, From 63e79853bfb736518dd05d594c3903e8f42a361f Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Wed, 25 Jun 2025 13:18:54 -0400 Subject: [PATCH 07/65] Updated export history function and added main test function --- .../vcell/modeldb/ExportHistoryDBDriver.java | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java new file mode 100644 index 0000000000..7231d2766a --- /dev/null +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -0,0 +1,190 @@ +package cbit.vcell.modeldb; + +import cbit.vcell.export.server.ExportSpecs; +import cbit.vcell.export.server.HumanReadableExportData; +import cbit.vcell.export.server.TimeSpecs; +import org.vcell.db.DatabaseSyntax; +import org.vcell.db.KeyFactory; +import org.vcell.util.DataAccessException; +import org.vcell.util.DependencyException; +import org.vcell.util.ObjectNotFoundException; +import org.vcell.util.PermissionException; +import org.vcell.util.document.User; + +import java.math.BigDecimal; +import java.sql.*; +import java.sql.SQLException; + +public class ExportHistoryDBDriver{ + public static final ExportHistoryTable exportHistoryTable = ExportHistoryTable.table; + public static final BioModelTable bioModelTable = BioModelTable.table; + public static final PublicationTable publicationTable = PublicationTable.table; + public static final UserTable userTable = UserTable.table; + public static final BioModelSimulationLinkTable bioModelSimLinkTable = BioModelSimulationLinkTable.table; + public static final BioModelSimContextLinkTable bioModelSimContextLinkTable = BioModelSimContextLinkTable.table; + public static final SimulationTable simTable = SimulationTable.table; + public static final SimContextTable simContextTable = SimContextTable.table; + + /** + * LocalDBManager constructor comment. + */ + public ExportHistoryDBDriver(DatabaseSyntax dbSyntax, KeyFactory keyFactory) { + + } + + + public void addExportHistory(Connection conn, + User user, + long jobID, + long modelRef, + String exportFormat, + Timestamp exportDate, + String uri, + ExportSpecs exportSpecs) + throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { + + String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server + "INSERT INTO vc_model_export_history (" + + "id, job_id, user_ref, model_ref, export_format, export_date, uri," + + "data_id, simulation_name, application_name, biomodel_name, variables," + + "start_time, end_time, saved_file_name, application_type, non_spatial," + + "z_slices, t_slices, num_variables" + + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + + PreparedStatement ps = conn.prepareStatement(vcmExpHiSQL); + HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); + TimeSpecs ts = exportSpecs.getTimeSpecs(); + String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); + + String timeRange = ts.toString(); + String[] time_parts = timeRange.split("/"); + BigDecimal startTime = new BigDecimal(time_parts[0]); + BigDecimal endTime = new BigDecimal(time_parts[1]); + + + ps.setLong(2, jobID); + ps.setLong(3, Long.parseLong(user.getID().toString())); + ps.setLong(4, modelRef); + ps.setString(5, exportFormat); + ps.setTimestamp(6, exportDate); + ps.setString(7, uri); + ps.setString(8, exportSpecs.getVCDataIdentifier().getID()); + ps.setString(9, meta.simulationName); + ps.setString(10, meta.applicationName); + ps.setString(11, meta.biomodelName); + ps.setArray(12, conn.createArrayOf("text", vars)); + ps.setBigDecimal(13, startTime); + ps.setBigDecimal(14, endTime); + ps.setString(15, meta.serverSavedFileName); + ps.setString(16, meta.applicationType); + ps.setBoolean(17, meta.nonSpatial); + ps.setInt(18, meta.zSlices); + ps.setInt(19, meta.tSlices); + ps.setInt(20, meta.numChannels); + ps.executeUpdate(); + + + String vcmExpHisPVSQL = // SQL statement for inserting into vc_model_parameter_value table in VCell server + "INSERT INTO vc_model_parameter_values (" + + "export_id, user_ref, model_ref, parameter_name," + + "parameter_original, parameter_changed" + + ") VALUES (?,?,?,?,?,?)"; + + PreparedStatement ps2 = conn.prepareStatement(vcmExpHisPVSQL); + + + for (String entry : meta.differentParameterValues) { + String[] parts = entry.split(":"); + if (parts.length == 3) { + //psParam.setLong (1, historyId); + ps2.setLong(2, Long.parseLong(user.getID().toString())); + ps2.setLong(3, modelRef); + ps2.setString(4, parts[0]); + ps2.setBigDecimal(5, new BigDecimal(parts[1])); + ps2.setBigDecimal(6, new BigDecimal(parts[2])); + ps2.addBatch(); + } + } + ps2.executeBatch(); + + } + + public static void main(Connection conn, + User user, + long jobID, + long modelRef, + String exportFormat, + Timestamp exportDate, + String uri, + ExportSpecs exportSpecs) + throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { + + String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server + "INSERT INTO vc_model_export_history (" + + "id, job_id, user_ref, model_ref, export_format, export_date, uri," + + "data_id, simulation_name, application_name, biomodel_name, variables," + + "start_time, end_time, saved_file_name, application_type, non_spatial," + + "z_slices, t_slices, num_variables" + + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + + PreparedStatement ps = conn.prepareStatement(vcmExpHiSQL); + HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); + TimeSpecs ts = exportSpecs.getTimeSpecs(); + String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); + + String timeRange = ts.toString(); + String[] time_parts = timeRange.split("/"); + BigDecimal startTime = new BigDecimal(time_parts[0]); + BigDecimal endTime = new BigDecimal(time_parts[1]); + + + ps.setLong(2, jobID); + ps.setLong(3, Long.parseLong(user.getID().toString())); + ps.setLong(4, modelRef); + ps.setString(5, exportFormat); + ps.setTimestamp(6, exportDate); + ps.setString(7, uri); + ps.setString(8, exportSpecs.getVCDataIdentifier().getID()); + ps.setString(9, meta.simulationName); + ps.setString(10, meta.applicationName); + ps.setString(11, meta.biomodelName); + ps.setArray(12, conn.createArrayOf("text", vars)); + ps.setBigDecimal(13, startTime); + ps.setBigDecimal(14, endTime); + ps.setString(15, meta.serverSavedFileName); + ps.setString(16, meta.applicationType); + ps.setBoolean(17, meta.nonSpatial); + ps.setInt(18, meta.zSlices); + ps.setInt(19, meta.tSlices); + ps.setInt(20, meta.numChannels); + ps.executeUpdate(); + + + String vcmExpHisPVSQL = // SQL statement for inserting into vc_model_parameter_value table in VCell server + "INSERT INTO vc_model_parameter_values (" + + "export_id, user_ref, model_ref, parameter_name," + + "parameter_original, parameter_changed" + + ") VALUES (?,?,?,?,?,?)"; + + PreparedStatement ps2 = conn.prepareStatement(vcmExpHisPVSQL); + + + for (String entry : meta.differentParameterValues) { + String[] parts = entry.split(":"); + if (parts.length == 3) { + //psParam.setLong (1, historyId); + ps2.setLong(2, Long.parseLong(user.getID().toString())); + ps2.setLong(3, modelRef); + ps2.setString(4, parts[0]); + ps2.setBigDecimal(5, new BigDecimal(parts[1])); + ps2.setBigDecimal(6, new BigDecimal(parts[2])); + ps2.addBatch(); + } + } + ps2.executeBatch(); + + } + +} From 2121e761be62883d7879c9e15cb52c82fcfcc47f Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Wed, 25 Jun 2025 13:57:05 -0400 Subject: [PATCH 08/65] Main Function --- .../java/cbit/vcell/modeldb/DBTopLevel.java | 23 +++++ .../vcell/modeldb/ExportHistoryDBDriver.java | 90 +++---------------- 2 files changed, 36 insertions(+), 77 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index f00a579010..5d175d5f93 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -2255,4 +2255,27 @@ public SimulationRep getSimulationRep(KeyValue simKey, boolean bEnableRetry) thr } } + public void insertExportHistory(User user, String exportHistoryValues, boolean bEnableRetry) throws SQLException, DataAccessException { + Object lock = new Object(); + Connection con = conFactory.getConnection(lock); + try { +// exportHistoryDB.addExportHistory(con, user, exportHistoryValues); + } catch (Throwable e) { + lg.error(e.getMessage(),e); + try { + con.rollback(); + }catch (Throwable rbe){ + lg.error("exception during rollback, bEnableRetry = "+bEnableRetry, rbe); + } + if (bEnableRetry && isBadConnection(con)) { + conFactory.failed(con,lock); + insertExportHistory(user, exportHistoryValues, false); + }else{ + handle_DataAccessException_SQLException(e); + } + }finally{ + conFactory.release(con,lock); + } + } + } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 7231d2766a..0024d725cf 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -1,5 +1,6 @@ package cbit.vcell.modeldb; +import cbit.vcell.export.server.ExportFormat; import cbit.vcell.export.server.ExportSpecs; import cbit.vcell.export.server.HumanReadableExportData; import cbit.vcell.export.server.TimeSpecs; @@ -9,11 +10,11 @@ import org.vcell.util.DependencyException; import org.vcell.util.ObjectNotFoundException; import org.vcell.util.PermissionException; +import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; import java.math.BigDecimal; import java.sql.*; -import java.sql.SQLException; public class ExportHistoryDBDriver{ public static final ExportHistoryTable exportHistoryTable = ExportHistoryTable.table; @@ -28,7 +29,7 @@ public class ExportHistoryDBDriver{ /** * LocalDBManager constructor comment. */ - public ExportHistoryDBDriver(DatabaseSyntax dbSyntax, KeyFactory keyFactory) { + public ExportHistoryDBDriver(DatabaseSyntax databaseSyntax, KeyFactory keyFactory) { } @@ -37,7 +38,7 @@ public void addExportHistory(Connection conn, User user, long jobID, long modelRef, - String exportFormat, + ExportFormat exportFormat, Timestamp exportDate, String uri, ExportSpecs exportSpecs) @@ -66,7 +67,7 @@ public void addExportHistory(Connection conn, ps.setLong(2, jobID); ps.setLong(3, Long.parseLong(user.getID().toString())); ps.setLong(4, modelRef); - ps.setString(5, exportFormat); + ps.setString(5, exportFormat.toString()); ps.setTimestamp(6, exportDate); ps.setString(7, uri); ps.setString(8, exportSpecs.getVCDataIdentifier().getID()); @@ -110,80 +111,15 @@ public void addExportHistory(Connection conn, } - public static void main(Connection conn, - User user, - long jobID, - long modelRef, - String exportFormat, - Timestamp exportDate, - String uri, - ExportSpecs exportSpecs) - throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { - - String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server - "INSERT INTO vc_model_export_history (" + - "id, job_id, user_ref, model_ref, export_format, export_date, uri," + - "data_id, simulation_name, application_name, biomodel_name, variables," + - "start_time, end_time, saved_file_name, application_type, non_spatial," + - "z_slices, t_slices, num_variables" + - ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; - - - PreparedStatement ps = conn.prepareStatement(vcmExpHiSQL); - HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); - TimeSpecs ts = exportSpecs.getTimeSpecs(); - String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); - - String timeRange = ts.toString(); - String[] time_parts = timeRange.split("/"); - BigDecimal startTime = new BigDecimal(time_parts[0]); - BigDecimal endTime = new BigDecimal(time_parts[1]); - - - ps.setLong(2, jobID); - ps.setLong(3, Long.parseLong(user.getID().toString())); - ps.setLong(4, modelRef); - ps.setString(5, exportFormat); - ps.setTimestamp(6, exportDate); - ps.setString(7, uri); - ps.setString(8, exportSpecs.getVCDataIdentifier().getID()); - ps.setString(9, meta.simulationName); - ps.setString(10, meta.applicationName); - ps.setString(11, meta.biomodelName); - ps.setArray(12, conn.createArrayOf("text", vars)); - ps.setBigDecimal(13, startTime); - ps.setBigDecimal(14, endTime); - ps.setString(15, meta.serverSavedFileName); - ps.setString(16, meta.applicationType); - ps.setBoolean(17, meta.nonSpatial); - ps.setInt(18, meta.zSlices); - ps.setInt(19, meta.tSlices); - ps.setInt(20, meta.numChannels); - ps.executeUpdate(); - - - String vcmExpHisPVSQL = // SQL statement for inserting into vc_model_parameter_value table in VCell server - "INSERT INTO vc_model_parameter_values (" + - "export_id, user_ref, model_ref, parameter_name," + - "parameter_original, parameter_changed" + - ") VALUES (?,?,?,?,?,?)"; - - PreparedStatement ps2 = conn.prepareStatement(vcmExpHisPVSQL); - - - for (String entry : meta.differentParameterValues) { - String[] parts = entry.split(":"); - if (parts.length == 3) { - //psParam.setLong (1, historyId); - ps2.setLong(2, Long.parseLong(user.getID().toString())); - ps2.setLong(3, modelRef); - ps2.setString(4, parts[0]); - ps2.setBigDecimal(5, new BigDecimal(parts[1])); - ps2.setBigDecimal(6, new BigDecimal(parts[2])); - ps2.addBatch(); - } + public static void main(String[] args) throws SQLException, PermissionException, DataAccessException { + try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "quarkus", "quarkus")){ + ExportHistoryDBDriver dbDriver = new ExportHistoryDBDriver(null, null); + ExportSpecs exportSpecs = new ExportSpecs(null, null, null, null, null, null, + null, null); + dbDriver.addExportHistory(connection, new User("Administrator", new KeyValue("2")), 1, 2, ExportFormat.N5, null, null, exportSpecs); + } catch (SQLException e){ + System.err.println("SQLException: " + e.getMessage()); } - ps2.executeBatch(); } From 2f6d060c19fa23ca450ce258076a192ef3cc7afe Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Fri, 27 Jun 2025 09:31:24 -0400 Subject: [PATCH 09/65] Added implementation for remove export history and get user history --- .../vcell/modeldb/ExportHistoryDBDriver.java | 115 ++++++++++++++++-- 1 file changed, 104 insertions(+), 11 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 0024d725cf..981e2a6b08 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -1,9 +1,8 @@ package cbit.vcell.modeldb; -import cbit.vcell.export.server.ExportFormat; -import cbit.vcell.export.server.ExportSpecs; -import cbit.vcell.export.server.HumanReadableExportData; -import cbit.vcell.export.server.TimeSpecs; +import cbit.vcell.export.server.*; +import cbit.vcell.solver.VCSimulationDataIdentifier; +import cbit.vcell.solver.VCSimulationIdentifier; import org.vcell.db.DatabaseSyntax; import org.vcell.db.KeyFactory; import org.vcell.util.DataAccessException; @@ -12,9 +11,12 @@ import org.vcell.util.PermissionException; import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; +import org.vcell.util.document.VCDataIdentifier; import java.math.BigDecimal; import java.sql.*; +import java.util.ArrayList; +import java.util.HashMap; public class ExportHistoryDBDriver{ public static final ExportHistoryTable exportHistoryTable = ExportHistoryTable.table; @@ -60,10 +62,10 @@ public void addExportHistory(Connection conn, String timeRange = ts.toString(); String[] time_parts = timeRange.split("/"); - BigDecimal startTime = new BigDecimal(time_parts[0]); - BigDecimal endTime = new BigDecimal(time_parts[1]); - + BigDecimal startTime = new BigDecimal(ts.getBeginTimeIndex()); + BigDecimal endTime = new BigDecimal(ts.getEndTimeIndex()); + ps.setLong(1, 1); //change once key values issue resolved ps.setLong(2, jobID); ps.setLong(3, Long.parseLong(user.getID().toString())); ps.setLong(4, modelRef); @@ -98,7 +100,7 @@ public void addExportHistory(Connection conn, for (String entry : meta.differentParameterValues) { String[] parts = entry.split(":"); if (parts.length == 3) { - //psParam.setLong (1, historyId); + ps2.setLong (1, 1); //change once key values issue resolved ps2.setLong(2, Long.parseLong(user.getID().toString())); ps2.setLong(3, modelRef); ps2.setString(4, parts[0]); @@ -111,12 +113,103 @@ public void addExportHistory(Connection conn, } + public void deleteExportHistory(Connection conn, ExportSpecs exportSpecs) throws SQLException { + + String selectSQL = "SELECT id FROM vc_model_export_history WHERE data_id = ?"; + try (PreparedStatement psSel = conn.prepareStatement(selectSQL)) { + psSel.setString(1, exportSpecs.getVCDataIdentifier().getID()); + try (ResultSet rs = psSel.executeQuery()) { + while (rs.next()) { + long historyId = rs.getLong(1); + + try (PreparedStatement psDelParams = conn.prepareStatement( + "DELETE FROM vc_model_parameter_values WHERE export_id = ?")) { + psDelParams.setLong(1, historyId); + psDelParams.executeUpdate(); + } + + try (PreparedStatement psDelHist = conn.prepareStatement( + "DELETE FROM vc_model_export_history WHERE id = ?")) { + psDelHist.setLong(1, historyId); + psDelHist.executeUpdate(); + } + } + } + } + } + + public ResultSet getExportHistoryForUser(Connection conn, User user) throws SQLException { + String sql = "SELECT * FROM vc_model_export_history WHERE user_ref = ?"; + PreparedStatement ps = conn.prepareStatement(sql); + ps.setLong(1, Long.parseLong(user.getID().toString())); + return ps.executeQuery(); + } + + public static void main(String[] args) throws SQLException, PermissionException, DataAccessException { try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "quarkus", "quarkus")){ ExportHistoryDBDriver dbDriver = new ExportHistoryDBDriver(null, null); - ExportSpecs exportSpecs = new ExportSpecs(null, null, null, null, null, null, - null, null); - dbDriver.addExportHistory(connection, new User("Administrator", new KeyValue("2")), 1, 2, ExportFormat.N5, null, null, exportSpecs); + + GeometrySpecs testGeometrySpecs = new GeometrySpecs(null, 100, 100, 1); + TimeSpecs testTimeSpecs = new TimeSpecs(0, 1, new double[]{1, 1}, 1); + String[] testVarNames = new String[]{"A", "B"}; + VariableSpecs testVariableSpecs = new VariableSpecs(testVarNames, 1); + + KeyValue simKey = new KeyValue("12345"); + + + User owner = new User("Administrator", new KeyValue("2")); + + + VCSimulationIdentifier vcSimID = new VCSimulationIdentifier(simKey, owner); + + VCDataIdentifier vcdID = new VCSimulationDataIdentifier(vcSimID,456); + String dataID = vcdID.getID(); + + FormatSpecificSpecs testFormatSpecificSpecs = new FormatSpecificSpecs() { + @Override + public boolean equals(Object obj) { + + return this == obj; + } + @Override + public String toString() { + return "DummyFormatSpecificSpecs"; + } + }; + + + + HumanReadableExportData meta = new HumanReadableExportData( + "MySimulation", + "MyApp", + "MyBioModel", + new ArrayList<>(), + "test", + "result.n5", + false, + new HashMap<>() + ); + + Timestamp testExportDate = new Timestamp(System.currentTimeMillis()); + + ExportSpecs exportSpecs = new ExportSpecs(vcdID, ExportFormat.N5, testVariableSpecs, testTimeSpecs, testGeometrySpecs, testFormatSpecificSpecs, + "testsim", "testname"); + exportSpecs.setExportMetaData(meta); + + dbDriver.addExportHistory(connection, new User("Administrator", new KeyValue("2")), 1, 2, ExportFormat.N5, testExportDate, "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName\\u003d3681309072", exportSpecs); + + System.out.println("=== Test get before deletion ==="); + try (ResultSet rs = dbDriver.getExportHistoryForUser(connection, owner)) { + while (rs.next()) { + System.out.println("id=" + rs.getLong("id") + + ", data_id=" + rs.getString("data_id") + + ", export_format=" + rs.getString("export_format")); + } + } + dbDriver.deleteExportHistory(connection, exportSpecs); + + } catch (SQLException e){ System.err.println("SQLException: " + e.getMessage()); } From 47a83f4f8cba49c102aee80a6ea588ef48e04e49 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 30 Jun 2025 13:33:37 -0400 Subject: [PATCH 10/65] Export History Tests Skeleton --- .../org/vcell/restq/ExportHistoryTest.java | 74 +++++++++++++++++++ .../java/cbit/vcell/modeldb/DBTopLevel.java | 4 +- .../vcell/modeldb/DatabaseServerImpl.java | 6 ++ .../vcell/modeldb/ExportHistoryDBDriver.java | 30 ++++---- 4 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java new file mode 100644 index 0000000000..5e9361bef9 --- /dev/null +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -0,0 +1,74 @@ +package org.vcell.restq; + +import cbit.vcell.biomodel.BioModel; +import cbit.vcell.mapping.MappingException; +import cbit.vcell.modeldb.DatabaseServerImpl; +import cbit.vcell.resource.PropertyLoader; +import cbit.vcell.xml.XMLSource; +import cbit.vcell.xml.XmlHelper; +import cbit.vcell.xml.XmlParseException; +import io.quarkus.test.junit.QuarkusTest; +import jakarta.inject.Inject; +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.junit.jupiter.api.*; +import org.vcell.restclient.ApiException; +import org.vcell.restq.config.CDIVCellConfigProvider; +import org.vcell.restq.db.AgroalConnectionFactory; +import org.vcell.util.BigString; +import org.vcell.util.DataAccessException; +import org.vcell.util.document.User; + +import java.beans.PropertyVetoException; +import java.io.IOException; +import java.sql.SQLException; + +// TODO: Use GenericVCMLTests class for the principle tests for VCDocuments +@QuarkusTest +public class ExportHistoryTest { + + @ConfigProperty(name = "quarkus.http.test-port") + Integer testPort; + + @Inject + AgroalConnectionFactory agroalConnectionFactory; + + + private DatabaseServerImpl databaseServer; + private BioModel savedBioModel; + + + @BeforeAll + public static void setupConfig(){ + PropertyLoader.setConfigProvider(new CDIVCellConfigProvider()); + } + + @BeforeEach + public void createClients() throws ApiException, DataAccessException, PropertyVetoException, XmlParseException, IOException { + databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); + BioModel bioModel = TestEndpointUtils.getTestBioModel(); + BigString bioModelXML = databaseServer.saveBioModel(TestEndpointUtils.administratorUser, new BigString(XmlHelper.bioModelToXML(bioModel)), new String[]{}); + savedBioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelXML.toString())); + } + + @AfterEach + public void removeOIDCMappings() throws SQLException, DataAccessException { + TestEndpointUtils.clearAllBioModelEntries(agroalConnectionFactory); + } + + @Test + public void testAddExportHistory() { + User user = TestEndpointUtils.administratorUser; + + + } + + @Test + public void testDeleteExportHistory() { + + } + + @Test + public void testGetExportHistory() { + + } +} diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index 5d175d5f93..dc7e2425d3 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -2255,11 +2255,11 @@ public SimulationRep getSimulationRep(KeyValue simKey, boolean bEnableRetry) thr } } - public void insertExportHistory(User user, String exportHistoryValues, boolean bEnableRetry) throws SQLException, DataAccessException { + public void insertExportHistory(User user, ExportHistoryDBDriver.ExportHistory exportHistoryValues, boolean bEnableRetry) throws SQLException, DataAccessException { Object lock = new Object(); Connection con = conFactory.getConnection(lock); try { -// exportHistoryDB.addExportHistory(con, user, exportHistoryValues); + exportHistoryDB.addExportHistory(con, user, exportHistoryValues); } catch (Throwable e) { lg.error(e.getMessage(),e); try { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java index a131f8f40c..1a1d456d4f 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java @@ -1355,4 +1355,10 @@ public BigString saveVCImageAs(User user, BigString vcImageXML, java.lang.String } } +public void addExportHistory(User user, ExportHistoryDBDriver.ExportHistory exportHistory) throws DataAccessException { + try { + dbTop.insertExportHistory(user, exportHistory, true); + } catch (SQLException e) { + throw new DataAccessException(e); + } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 981e2a6b08..01334f8b89 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -35,15 +35,16 @@ public ExportHistoryDBDriver(DatabaseSyntax databaseSyntax, KeyFactory keyFactor } - - public void addExportHistory(Connection conn, - User user, - long jobID, - long modelRef, - ExportFormat exportFormat, - Timestamp exportDate, - String uri, - ExportSpecs exportSpecs) + public record ExportHistory( + long jobID, + long modelRef, + ExportFormat exportFormat, + Timestamp exportDate, + String uri, + ExportSpecs exportSpecs + ){ } + + public void addExportHistory(Connection conn, User user, ExportHistory exportHistory) throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server @@ -54,7 +55,8 @@ public void addExportHistory(Connection conn, "z_slices, t_slices, num_variables" + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; - + ExportSpecs exportSpecs = exportHistory.exportSpecs; + long modelRef = exportHistory.modelRef; PreparedStatement ps = conn.prepareStatement(vcmExpHiSQL); HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); TimeSpecs ts = exportSpecs.getTimeSpecs(); @@ -66,12 +68,12 @@ public void addExportHistory(Connection conn, BigDecimal endTime = new BigDecimal(ts.getEndTimeIndex()); ps.setLong(1, 1); //change once key values issue resolved - ps.setLong(2, jobID); + ps.setLong(2, exportHistory.jobID); ps.setLong(3, Long.parseLong(user.getID().toString())); ps.setLong(4, modelRef); - ps.setString(5, exportFormat.toString()); - ps.setTimestamp(6, exportDate); - ps.setString(7, uri); + ps.setString(5, exportHistory.exportFormat.toString()); + ps.setTimestamp(6, exportHistory.exportDate); + ps.setString(7, exportHistory.uri); ps.setString(8, exportSpecs.getVCDataIdentifier().getID()); ps.setString(9, meta.simulationName); ps.setString(10, meta.applicationName); From 5d13715be23a93266679bd1ca12fafc837973a5d Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:49:27 -0400 Subject: [PATCH 11/65] Added export history test and updated export history key access --- .../org/vcell/restq/ExportHistoryTest.java | 184 +++++++++++++++++- .../java/cbit/vcell/modeldb/DBTopLevel.java | 1 + .../vcell/modeldb/ExportHistoryDBDriver.java | 96 ++++----- 3 files changed, 230 insertions(+), 51 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index 5e9361bef9..c5df9b746f 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -1,9 +1,14 @@ package org.vcell.restq; import cbit.vcell.biomodel.BioModel; +import cbit.vcell.export.server.*; import cbit.vcell.mapping.MappingException; import cbit.vcell.modeldb.DatabaseServerImpl; +import cbit.vcell.modeldb.ExportHistoryDBDriver; import cbit.vcell.resource.PropertyLoader; +import cbit.vcell.simdata.SpatialSelection; +import cbit.vcell.solver.VCSimulationDataIdentifier; +import cbit.vcell.solver.VCSimulationIdentifier; import cbit.vcell.xml.XMLSource; import cbit.vcell.xml.XmlHelper; import cbit.vcell.xml.XmlParseException; @@ -11,16 +16,38 @@ import jakarta.inject.Inject; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.junit.jupiter.api.*; +import org.vcell.restclient.ApiClient; import org.vcell.restclient.ApiException; import org.vcell.restq.config.CDIVCellConfigProvider; import org.vcell.restq.db.AgroalConnectionFactory; +import org.vcell.restq.handlers.ExportResource; import org.vcell.util.BigString; import org.vcell.util.DataAccessException; +import org.vcell.util.DependencyException; +import org.vcell.util.ObjectNotFoundException; +import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; +import org.vcell.util.document.VCDataIdentifier; +import cbit.vcell.export.server.ExportFormat; +import cbit.vcell.export.server.ExportSpecs; import java.beans.PropertyVetoException; import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +import static org.bouncycastle.math.raw.Nat.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertEquals; +import static org.vcell.sybil.util.http.pathwaycommons.PCRParameter.Output.xml; +import static org.vcell.util.VCAssert.assertFalse; +import static org.vcell.util.VCAssert.assertTrue; // TODO: Use GenericVCMLTests class for the principle tests for VCDocuments @QuarkusTest @@ -32,10 +59,14 @@ public class ExportHistoryTest { @Inject AgroalConnectionFactory agroalConnectionFactory; + private ApiClient apiClient; + private User testUser; private DatabaseServerImpl databaseServer; private BioModel savedBioModel; + private ExportSpecs exportSpecs; + @BeforeAll public static void setupConfig(){ @@ -48,6 +79,54 @@ public void createClients() throws ApiException, DataAccessException, PropertyVe BioModel bioModel = TestEndpointUtils.getTestBioModel(); BigString bioModelXML = databaseServer.saveBioModel(TestEndpointUtils.administratorUser, new BigString(XmlHelper.bioModelToXML(bioModel)), new String[]{}); savedBioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelXML.toString())); + + + VCSimulationIdentifier vcSimId = new VCSimulationIdentifier( + new KeyValue("000"), TestEndpointUtils.administratorUser + ); + VCDataIdentifier vcdId = new VCSimulationDataIdentifier(vcSimId, 0); + + + GeometrySpecs geometrySpecs = new GeometrySpecs(null, 1, 1, 1); + + + double[] times = new double[]{0.0, 1.0}; + TimeSpecs timeSpecs = new TimeSpecs(0, 1, times, times.length); + + + VariableSpecs variableSpecs = new VariableSpecs(new String[]{"X"}, 1); + + + FormatSpecificSpecs formatSpecific = new FormatSpecificSpecs() { + @Override public boolean equals(Object o) { return this==o; } + @Override public String toString() { return "DUMMY"; } + }; + + + HumanReadableExportData meta = new HumanReadableExportData( + "simName", // simulation name + "appName", // application name + savedBioModel.getName(), // biomodel name + new ArrayList(), // no parameter changes + vcdId.getID(), // dataId + "out.n5", // serverSavedFileName + false, // nonSpatial? + new HashMap<>() // no per‐slice parameters + ); + + + exportSpecs = new ExportSpecs( + vcdId, + ExportFormat.N5, + variableSpecs, + timeSpecs, + geometrySpecs, + formatSpecific, + "simName", + savedBioModel.getName() + ); + exportSpecs.setExportMetaData(meta); + } @AfterEach @@ -55,20 +134,119 @@ public void removeOIDCMappings() throws SQLException, DataAccessException { TestEndpointUtils.clearAllBioModelEntries(agroalConnectionFactory); } + @Test public void testAddExportHistory() { User user = TestEndpointUtils.administratorUser; + Timestamp now = new Timestamp(System.currentTimeMillis()); + + try (Connection conn = agroalConnectionFactory.getConnection(null)) { + ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); + + + driver.addExportHistory( + conn, + user, + new ExportHistoryDBDriver.ExportHistory( + 42L, + Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), + ExportFormat.N5, + now, + "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", + exportSpecs + ) + ); + + try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { + Assertions.assertTrue(rs.next(), "expected one record"); + Assertions.assertEquals(42L, rs.getLong("job_id")); + Assertions.assertEquals("https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", rs.getString("uri")); + Assertions.assertEquals("N5", rs.getString("export_format")); + Assertions.assertFalse(rs.next(), "only one record should exist"); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } catch (ObjectNotFoundException e) { + throw new RuntimeException(e); + } catch (DependencyException e) { + throw new RuntimeException(e); + } catch (DataAccessException e) { + throw new RuntimeException(e); + } } @Test - public void testDeleteExportHistory() { + public void testDeleteExportHistory() throws SQLException { + User user = TestEndpointUtils.administratorUser; + Timestamp now = new Timestamp(System.currentTimeMillis()); + + try (Connection conn = agroalConnectionFactory.getConnection(null)) { + ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); + + + driver.addExportHistory(conn, user, + new ExportHistoryDBDriver.ExportHistory(7L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "to-delete", exportSpecs) + ); + + + try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { + Assertions.assertTrue(rs.next()); + Assertions.assertEquals("to-delete", rs.getString("uri")); + } + + driver.deleteExportHistory(conn, exportSpecs); + + try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { + Assertions.assertFalse(rs.next()); + Assertions.assertNotEquals("to-delete", rs.getString("uri")); + } + + + driver.deleteExportHistory(conn, exportSpecs); + + + try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { + assertFalse(rs.next(),"No rows should remain after deletion"); + } + } catch (ObjectNotFoundException e) { + throw new RuntimeException(e); + } catch (DependencyException e) { + throw new RuntimeException(e); + } catch (DataAccessException e) { + throw new RuntimeException(e); + } } @Test - public void testGetExportHistory() { - + public void testGetExportHistory() throws SQLException, DataAccessException { + User user = TestEndpointUtils.administratorUser; + Timestamp now = new Timestamp(System.currentTimeMillis()); + + try (Connection conn = agroalConnectionFactory.getConnection(null)) { + ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); + + driver.addExportHistory(conn, user, + new ExportHistoryDBDriver.ExportHistory(100L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri100", exportSpecs) + ); + driver.addExportHistory(conn, user, + new ExportHistoryDBDriver.ExportHistory(101L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri101", exportSpecs) + ); + + int count = 0; + try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { + while (rs.next()) { + count++; + Assertions.assertTrue(rs.getString("uri").startsWith("uri")); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + Assertions.assertEquals(2, count); + } } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index dc7e2425d3..d86eed7b1e 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -15,6 +15,7 @@ import cbit.sql.QueryHashtable; import cbit.sql.RecordChangedException; import cbit.vcell.biomodel.BioModelMetaData; +import cbit.vcell.export.server.ExportSpecs; import cbit.vcell.field.FieldDataAllDBEntries; import cbit.vcell.field.FieldDataExternalDataIDEntry; import cbit.vcell.field.io.CopyFieldDataResult; diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 01334f8b89..3e66a94ca6 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -67,11 +67,18 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis BigDecimal startTime = new BigDecimal(ts.getBeginTimeIndex()); BigDecimal endTime = new BigDecimal(ts.getEndTimeIndex()); - ps.setLong(1, 1); //change once key values issue resolved + long historyId; + try ( Statement seqStmt = conn.createStatement(); + ResultSet rs = seqStmt.executeQuery("SELECT nextval('newSeq')") ) { + rs.next(); + historyId = rs.getLong(1); + } + + ps.setLong(1, historyId); //change once key values issue resolved ps.setLong(2, exportHistory.jobID); ps.setLong(3, Long.parseLong(user.getID().toString())); ps.setLong(4, modelRef); - ps.setString(5, exportHistory.exportFormat.toString()); + ps.setString(5, exportHistory.exportFormat.name()); ps.setTimestamp(6, exportHistory.exportDate); ps.setString(7, exportHistory.uri); ps.setString(8, exportSpecs.getVCDataIdentifier().getID()); @@ -102,7 +109,7 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis for (String entry : meta.differentParameterValues) { String[] parts = entry.split(":"); if (parts.length == 3) { - ps2.setLong (1, 1); //change once key values issue resolved + ps2.setLong (1, historyId); //change once key values issue resolved ps2.setLong(2, Long.parseLong(user.getID().toString())); ps2.setLong(3, modelRef); ps2.setString(4, parts[0]); @@ -125,7 +132,7 @@ public void deleteExportHistory(Connection conn, ExportSpecs exportSpecs) throws long historyId = rs.getLong(1); try (PreparedStatement psDelParams = conn.prepareStatement( - "DELETE FROM vc_model_parameter_values WHERE export_id = ?")) { + "DELETE FROM vc_model_parameter_values WHERE id = ?")) { psDelParams.setLong(1, historyId); psDelParams.executeUpdate(); } @@ -149,73 +156,66 @@ public ResultSet getExportHistoryForUser(Connection conn, User user) throws SQLE public static void main(String[] args) throws SQLException, PermissionException, DataAccessException { - try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "quarkus", "quarkus")){ + try (Connection connection = DriverManager.getConnection( + "jdbc:postgresql://localhost:5432/postgres", "quarkus", "quarkus")) { + ExportHistoryDBDriver dbDriver = new ExportHistoryDBDriver(null, null); + GeometrySpecs testGeometrySpecs = new GeometrySpecs(null, 100, 100, 1); TimeSpecs testTimeSpecs = new TimeSpecs(0, 1, new double[]{1, 1}, 1); String[] testVarNames = new String[]{"A", "B"}; VariableSpecs testVariableSpecs = new VariableSpecs(testVarNames, 1); - KeyValue simKey = new KeyValue("12345"); - - - User owner = new User("Administrator", new KeyValue("2")); - - - VCSimulationIdentifier vcSimID = new VCSimulationIdentifier(simKey, owner); - - VCDataIdentifier vcdID = new VCSimulationDataIdentifier(vcSimID,456); - String dataID = vcdID.getID(); - + User user = new User("Administrator", new KeyValue("2")); + VCSimulationIdentifier vcSimID = new VCSimulationIdentifier(simKey, user); + VCDataIdentifier vcdID = new VCSimulationDataIdentifier(vcSimID, 456); FormatSpecificSpecs testFormatSpecificSpecs = new FormatSpecificSpecs() { - @Override - public boolean equals(Object obj) { - - return this == obj; - } - @Override - public String toString() { - return "DummyFormatSpecificSpecs"; - } + @Override public boolean equals(Object obj) { return this == obj; } + @Override public String toString() { return "DummyFormatSpecificSpecs"; } }; - - - HumanReadableExportData meta = new HumanReadableExportData( - "MySimulation", - "MyApp", - "MyBioModel", - new ArrayList<>(), - "test", - "result.n5", - false, - new HashMap<>() + "MySimulation","MyApp","MyBioModel", + new ArrayList<>(), "result.n5","N5", false, new HashMap<>() ); - Timestamp testExportDate = new Timestamp(System.currentTimeMillis()); - - ExportSpecs exportSpecs = new ExportSpecs(vcdID, ExportFormat.N5, testVariableSpecs, testTimeSpecs, testGeometrySpecs, testFormatSpecificSpecs, - "testsim", "testname"); + ExportSpecs exportSpecs = new ExportSpecs( + vcdID, ExportFormat.N5, testVariableSpecs, testTimeSpecs, + testGeometrySpecs, testFormatSpecificSpecs, "testsim","testname" + ); exportSpecs.setExportMetaData(meta); - dbDriver.addExportHistory(connection, new User("Administrator", new KeyValue("2")), 1, 2, ExportFormat.N5, testExportDate, "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName\\u003d3681309072", exportSpecs); + + ExportHistoryDBDriver.ExportHistory history = new ExportHistoryDBDriver.ExportHistory( + /*jobID=*/ 1, + /*modelRef=*/ 2, + /*format=*/ ExportFormat.N5, + /*date=*/ testExportDate, + /*uri=*/ "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", + /*specs=*/ exportSpecs + ); + + + dbDriver.addExportHistory(connection, user, history); System.out.println("=== Test get before deletion ==="); - try (ResultSet rs = dbDriver.getExportHistoryForUser(connection, owner)) { + try (ResultSet rs = dbDriver.getExportHistoryForUser(connection, user)) { while (rs.next()) { - System.out.println("id=" + rs.getLong("id") - + ", data_id=" + rs.getString("data_id") - + ", export_format=" + rs.getString("export_format")); + System.out.println( + "id=" + rs.getLong("id") + + ", data_id=" + rs.getString("data_id") + + ", export_format=" + rs.getString("export_format") + ); } } - dbDriver.deleteExportHistory(connection, exportSpecs); - } catch (SQLException e){ + dbDriver.deleteExportHistory(connection, exportSpecs); + + } catch (SQLException e) { System.err.println("SQLException: " + e.getMessage()); } - } + } From 5e3f45d84fbc53242b141e7108bb75b3fc94f458 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Mon, 11 Aug 2025 10:17:25 -0400 Subject: [PATCH 12/65] Altered export history sql framework and implementation (WIP) --- .../vcell/modeldb/ExportHistoryDBDriver.java | 129 ++++++-------- .../vcell/modeldb/ExportHistoryTable.java | 164 ++++++++++++++++++ .../modeldb/ModelParameterValuesTable.java | 96 ++++++++++ 3 files changed, 317 insertions(+), 72 deletions(-) create mode 100644 vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java create mode 100644 vcell-server/src/main/java/cbit/vcell/modeldb/ModelParameterValuesTable.java diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 3e66a94ca6..4811fc605d 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -17,9 +17,11 @@ import java.sql.*; import java.util.ArrayList; import java.util.HashMap; +import java.util.StringJoiner; public class ExportHistoryDBDriver{ public static final ExportHistoryTable exportHistoryTable = ExportHistoryTable.table; + public static final ModelParameterValuesTable modelParameterValuesTable = ModelParameterValuesTable.table; public static final BioModelTable bioModelTable = BioModelTable.table; public static final PublicationTable publicationTable = PublicationTable.table; public static final UserTable userTable = UserTable.table; @@ -28,6 +30,7 @@ public class ExportHistoryDBDriver{ public static final SimulationTable simTable = SimulationTable.table; public static final SimContextTable simContextTable = SimContextTable.table; + /** * LocalDBManager constructor comment. */ @@ -36,89 +39,71 @@ public ExportHistoryDBDriver(DatabaseSyntax databaseSyntax, KeyFactory keyFactor } public record ExportHistory( - long jobID, - long modelRef, + long jobID, + long modelRef, ExportFormat exportFormat, Timestamp exportDate, - String uri, + String uri, ExportSpecs exportSpecs - ){ } + ){} public void addExportHistory(Connection conn, User user, ExportHistory exportHistory) throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { - String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server - "INSERT INTO vc_model_export_history (" + - "id, job_id, user_ref, model_ref, export_format, export_date, uri," + - "data_id, simulation_name, application_name, biomodel_name, variables," + - "start_time, end_time, saved_file_name, application_type, non_spatial," + - "z_slices, t_slices, num_variables" + - ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; - - ExportSpecs exportSpecs = exportHistory.exportSpecs; - long modelRef = exportHistory.modelRef; - PreparedStatement ps = conn.prepareStatement(vcmExpHiSQL); - HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); - TimeSpecs ts = exportSpecs.getTimeSpecs(); - String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); - - String timeRange = ts.toString(); - String[] time_parts = timeRange.split("/"); - BigDecimal startTime = new BigDecimal(ts.getBeginTimeIndex()); - BigDecimal endTime = new BigDecimal(ts.getEndTimeIndex()); - - long historyId; - try ( Statement seqStmt = conn.createStatement(); - ResultSet rs = seqStmt.executeQuery("SELECT nextval('newSeq')") ) { - rs.next(); - historyId = rs.getLong(1); + ExportSpecs specs = exportHistory.exportSpecs; + HumanReadableExportData meta = specs.getHumanReadableExportData(); + TimeSpecs ts = specs.getTimeSpecs(); + String[] vars = specs.getVariableSpecs().getVariableNames(); + // comma-separate the variable names + String variablesCsv = String.join(",", vars); + + // 1) insert into vc_model_export_history + String ehSQL = ExportHistoryTable.table.getInsertSQL(); + try (PreparedStatement ps = conn.prepareStatement(ehSQL)) { + ExportHistoryTable.table.bindForInsert(ps, + exportHistory.jobID, + Long.parseLong(user.getID().toString()), + exportHistory.modelRef, + exportHistory.exportFormat, + exportHistory.exportDate, + exportHistory.uri, + specs.getVCDataIdentifier().getID(), + meta.simulationName, + meta.applicationName, + meta.biomodelName, + variablesCsv, + BigDecimal.valueOf(ts.getBeginTimeIndex()), + BigDecimal.valueOf(ts.getEndTimeIndex()), + meta.serverSavedFileName, + meta.applicationType, + meta.nonSpatial, + meta.zSlices, + meta.tSlices, + meta.numChannels + ); + ps.executeUpdate(); } - ps.setLong(1, historyId); //change once key values issue resolved - ps.setLong(2, exportHistory.jobID); - ps.setLong(3, Long.parseLong(user.getID().toString())); - ps.setLong(4, modelRef); - ps.setString(5, exportHistory.exportFormat.name()); - ps.setTimestamp(6, exportHistory.exportDate); - ps.setString(7, exportHistory.uri); - ps.setString(8, exportSpecs.getVCDataIdentifier().getID()); - ps.setString(9, meta.simulationName); - ps.setString(10, meta.applicationName); - ps.setString(11, meta.biomodelName); - ps.setArray(12, conn.createArrayOf("text", vars)); - ps.setBigDecimal(13, startTime); - ps.setBigDecimal(14, endTime); - ps.setString(15, meta.serverSavedFileName); - ps.setString(16, meta.applicationType); - ps.setBoolean(17, meta.nonSpatial); - ps.setInt(18, meta.zSlices); - ps.setInt(19, meta.tSlices); - ps.setInt(20, meta.numChannels); - ps.executeUpdate(); - - - String vcmExpHisPVSQL = // SQL statement for inserting into vc_model_parameter_value table in VCell server - "INSERT INTO vc_model_parameter_values (" + - "export_id, user_ref, model_ref, parameter_name," + - "parameter_original, parameter_changed" + - ") VALUES (?,?,?,?,?,?)"; - - PreparedStatement ps2 = conn.prepareStatement(vcmExpHisPVSQL); - - - for (String entry : meta.differentParameterValues) { - String[] parts = entry.split(":"); - if (parts.length == 3) { - ps2.setLong (1, historyId); //change once key values issue resolved - ps2.setLong(2, Long.parseLong(user.getID().toString())); - ps2.setLong(3, modelRef); - ps2.setString(4, parts[0]); - ps2.setBigDecimal(5, new BigDecimal(parts[1])); - ps2.setBigDecimal(6, new BigDecimal(parts[2])); - ps2.addBatch(); + // 2) insert each parameter change + String pvSQL = ModelParameterValuesTable.table.getInsertSQL(); + try (PreparedStatement ps2 = conn.prepareStatement(pvSQL)) { + for (String entry : meta.differentParameterValues) { + String[] parts = entry.split(":"); + if (parts.length == 3) { + ModelParameterValuesTable.table.bindForInsert(ps2, + // note: you need the export_id FK—assumes you have it from a sequence + exportHistory.jobID, // if your PK is the jobID, else use the returned PK + Long.parseLong(user.getID().toString()), + exportHistory.modelRef, + parts[0], + new BigDecimal(parts[1]), + new BigDecimal(parts[2]) + ); + ps2.addBatch(); + } } + ps2.executeBatch(); } - ps2.executeBatch(); } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java new file mode 100644 index 0000000000..f55bb8602a --- /dev/null +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -0,0 +1,164 @@ +package cbit.vcell.modeldb; + +import cbit.sql.Field; +import cbit.sql.Table; +import cbit.vcell.export.server.ExportFormat; + +import java.math.BigDecimal; +import java.sql.*; +import java.util.StringJoiner; + +public class ExportHistoryTable extends Table { + private static final String TABLE_NAME = "vc_model_export_history"; + + public final Field jobId = new Field("job_id", Field.SQLDataType.varchar_50, "NOT NULL"); + + public final Field userRef = new Field("user_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + UserTable.REF_TYPE); + + public final Field modelRef = new Field("model_ref", Field.SQLDataType.integer, "NOT NULL " + ModelTable.REF_TYPE); + + public final Field exportFormat = new Field("export_format", Field.SQLDataType.varchar_50, "NOT NULL"); + public final Field exportDate = new Field("export_date", Field.SQLDataType.date, "NOT NULL"); + + public final Field uri = new Field("uri", Field.SQLDataType.varchar2_4000, "NOT NULL"); + public final Field dataId = new Field("data_id", Field.SQLDataType.varchar_255, "NOT NULL"); + public final Field simulationName = new Field("simulation_name", Field.SQLDataType.varchar_255, "NOT NULL"); + public final Field applicationName = new Field("application_name", Field.SQLDataType.varchar_255, "NOT NULL"); + public final Field biomodelName = new Field("biomodel_name", Field.SQLDataType.varchar_255, "NOT NULL"); + + public final Field variables = new Field("variables", Field.SQLDataType.varchar_255, "[] NOT NULL"); + public final Field startTime = new Field("start_time", Field.SQLDataType.integer_as_numeric, "NOT NULL"); + public final Field endTime = new Field("end_time", Field.SQLDataType.integer_as_numeric, "NOT NULL"); + public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_255, "NOT NULL"); + public final Field applicationType = new Field("application_type", Field.SQLDataType.varchar_50, "NOT NULL"); + public final Field nonSpatial = new Field("non_spatial", Field.SQLDataType.varchar_50, "NOT NULL"); + public final Field zSlices = new Field("z_slices", Field.SQLDataType.integer, "NOT NULL DEFAULT 0"); + public final Field tSlices = new Field("t_slices", Field.SQLDataType.integer, "NOT NULL DEFAULT 0"); + public final Field numVariables = new Field("num_variables", Field.SQLDataType.integer, "NOT NULL DEFAULT 0"); + + //public final Field insertDate = new Field("insert_date", Field.SQLDataType.date, "NOT NULL DEFAULT CURRENT_TIMESTAMP"); + + + private final Field fields[] = {jobId, userRef, modelRef, exportFormat, exportDate, uri, + dataId, simulationName, applicationName, biomodelName, variables, + startTime, endTime, savedFileName, applicationType, nonSpatial, + zSlices, tSlices, numVariables}; + + private final Field[] insertFields = { + jobId, userRef, modelRef, exportFormat, exportDate, uri, dataId, + simulationName, applicationName, biomodelName, variables, + startTime, endTime, savedFileName, applicationType, nonSpatial, + zSlices, tSlices, numVariables + }; + + public static final ExportHistoryTable table = new ExportHistoryTable(); + + private ExportHistoryTable() { + super(TABLE_NAME); + addFields(fields); + } + + public String getInsertSQL() { + + StringJoiner cols = new StringJoiner(",", "(", ")"); + for (Field f : insertFields) { + cols.add(f.getQualifiedColName()); + } + + StringJoiner ph = new StringJoiner(",", "(", ")"); + for (int i = 0; i < insertFields.length; i++) { + ph.add("?"); + } + return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString(); + } + public void bindForInsert( + PreparedStatement ps, + long jobIdValue, + long userRefValue, + long modelRefValue, + ExportFormat fmt, + Timestamp exportDateValue, + String uriValue, + String dataIdValue, + String simName, + String appName, + String bioName, + String variablesCsv, + BigDecimal startTimeValue, + BigDecimal endTimeValue, + String savedFileNameValue, + String applicationTypeValue, + boolean nonSpatialValue, + int zSlicesValue, + int tSlicesValue, + int numVariablesValue + ) throws SQLException { + int i = 1; + ps.setLong (i++, jobIdValue); + ps.setLong (i++, userRefValue); + ps.setLong (i++, modelRefValue); + ps.setString (i++, fmt.name()); + ps.setTimestamp (i++, exportDateValue); + ps.setString (i++, uriValue); + ps.setString (i++, dataIdValue); + ps.setString (i++, simName); + ps.setString (i++, appName); + ps.setString (i++, bioName); + ps.setString (i++, variablesCsv); + ps.setBigDecimal (i++, startTimeValue); + ps.setBigDecimal (i++, endTimeValue); + ps.setString (i++, savedFileNameValue); + ps.setString (i++, applicationTypeValue); + ps.setBoolean (i++, nonSpatialValue); + ps.setInt (i++, zSlicesValue); + ps.setInt (i++, tSlicesValue); + ps.setInt (i++, numVariablesValue); + } + public record ExportHistoryRecord(String jobID, long userRef, long modelRef, ExportFormat format, Timestamp date, + String uri, String dataID, String simName, String appName, String bioName, + BigDecimal startTime, BigDecimal endTime, String savedFile, String appType, + boolean nonSpatial, int zSlices, int tSlices, int numVars) { + } + + public ExportHistoryRecord getExportHistoryRecord(ResultSet rset, ExportHistoryRecord exportHistoryRecord) throws SQLException, SQLException { + + long userRef = rset.getLong((int) exportHistoryRecord.userRef); + long modelRef = rset.getLong((int) exportHistoryRecord.modelRef); + + // enums & timestamps + ExportFormat fmt = ExportFormat.valueOf(rset.getString(exportFormat.toString())); + Timestamp date = rset.getTimestamp(exportDate.toString()); + + // strings + String jobId = rset.getString(exportHistoryRecord.jobID); + String uriVal = rset.getString(uri.toString()); + String dataIdVal = rset.getString(dataId.toString()); + String simNameVal = rset.getString(simulationName.toString()); + String appNameVal = rset.getString(applicationName.toString()); + String bioNameVal = rset.getString(biomodelName.toString()); + + // text array of variables + Array sqlArr = rset.getArray(variables.toString()); + + // numeric ranges + BigDecimal startBt = rset.getBigDecimal(startTime.toString()); + BigDecimal endBt = rset.getBigDecimal(endTime.toString()); + + // more strings & flags + String savedFileVal = rset.getString(savedFileName.toString()); + String appTypeVal = rset.getString(applicationType.toString()); + boolean nonSp = rset.getBoolean(nonSpatial.toString()); + int zS = rset.getInt(zSlices.toString()); + int tS = rset.getInt(tSlices.toString()); + int numV = rset.getInt(numVariables.toString()); + + + + return new ExportHistoryRecord( + jobId, userRef, modelRef, fmt, date, + uriVal, dataIdVal, simNameVal, appNameVal, bioNameVal, + startBt, endBt, savedFileVal, appTypeVal, + nonSp, zS, tS, numV + ); + } +} diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ModelParameterValuesTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ModelParameterValuesTable.java new file mode 100644 index 0000000000..ffb4160f82 --- /dev/null +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ModelParameterValuesTable.java @@ -0,0 +1,96 @@ +package cbit.vcell.modeldb; + +import cbit.sql.Field; +import cbit.sql.Table; +import java.math.BigDecimal; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.StringJoiner; + +/** + * Defines the vc_model_parameter_values table and how to read rows from it. + */ +public class ModelParameterValuesTable extends Table { + private static final String TABLE_NAME = "vc_model_parameter_values"; + + /** FK back to vc_model_export_history.id */ + public final Field exportId = new Field("export_id", Field.SQLDataType.integer, "NOT NULL REFERENCES vc_model_export_history(id)"); + public final Field userRef = new Field("user_ref", Field.SQLDataType.integer, "NOT NULL " + UserTable.REF_TYPE); + public final Field modelRef = new Field("model_ref", Field.SQLDataType.integer, "NOT NULL " + ModelTable.REF_TYPE); + public final Field parameterName = new Field("parameter_name", Field.SQLDataType.varchar_50, "NOT NULL"); + public final Field parameterOriginal = new Field("parameter_original", Field.SQLDataType.number_as_real, "NOT NULL"); + public final Field parameterChanged = new Field("parameter_changed", Field.SQLDataType.number_as_real, "NOT NULL"); + + private final Field[] fields = { + exportId, + userRef, + modelRef, + parameterName, + parameterOriginal, + parameterChanged + }; + + private final Field[] insertFields = { + exportId, userRef, modelRef, parameterName, parameterOriginal, parameterChanged + }; + + public static final ModelParameterValuesTable table = new ModelParameterValuesTable(); + + private ModelParameterValuesTable() { + super(TABLE_NAME); + addFields(fields); + } + + + public String getInsertSQL() { + StringJoiner cols = new StringJoiner(",", "(", ")"); + for (Field f : insertFields) { + cols.add(f.getQualifiedColName()); + } + StringJoiner ph = new StringJoiner(",", "(", ")"); + for (int i = 0; i < insertFields.length; i++) { + ph.add("?"); + } + return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString(); + } + + public void bindForInsert( + PreparedStatement ps, + long exportIdValue, + long userRefValue, + long modelRefValue, + String parameterNameValue, + BigDecimal originalValue, + BigDecimal changedValue + ) throws SQLException { + int i=1; + ps.setLong (i++, exportIdValue); + ps.setLong (i++, userRefValue); + ps.setLong (i++, modelRefValue); + ps.setString (i++, parameterNameValue); + ps.setBigDecimal (i++, originalValue); + ps.setBigDecimal (i++, changedValue); + } + + public record ModelParameterValueRecord(long userRef, long modelRef, String parameterName, + BigDecimal parameterOriginal, BigDecimal parameterChanged) { + } + + + public ModelParameterValueRecord getModelParameterValueRecord(ResultSet rset, ModelParameterValueRecord modelParameterValueRecord) throws SQLException { + long userRef = rset.getLong((int) modelParameterValueRecord.userRef); + long modelRef = rset.getLong((int) modelParameterValueRecord.modelRef); + String paramName = rset.getString(parameterName.toString()); + BigDecimal origVal = rset.getBigDecimal(parameterOriginal.toString()); + BigDecimal changedVal = rset.getBigDecimal(parameterChanged.toString()); + + return new ModelParameterValueRecord( + userRef, + modelRef, + paramName, + origVal, + changedVal + ); + } +} From 127a16d6735f680aeac1796ab1dfc3645ac84ec2 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Fri, 15 Aug 2025 14:11:10 -0400 Subject: [PATCH 13/65] Fixed sql parameter error --- .../org/vcell/restq/ExportHistoryTest.java | 7 +- .../vcell/modeldb/ExportHistoryDBDriver.java | 8 +- .../vcell/modeldb/ExportHistoryTable.java | 102 +++++++++--------- 3 files changed, 59 insertions(+), 58 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index c5df9b746f..4e6f0d8f05 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -37,6 +37,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -138,7 +139,7 @@ public void removeOIDCMappings() throws SQLException, DataAccessException { @Test public void testAddExportHistory() { User user = TestEndpointUtils.administratorUser; - Timestamp now = new Timestamp(System.currentTimeMillis()); + Timestamp now = Timestamp.from(Instant.now()); try (Connection conn = agroalConnectionFactory.getConnection(null)) { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); @@ -166,9 +167,7 @@ public void testAddExportHistory() { } catch (SQLException e) { throw new RuntimeException(e); } - } catch (SQLException e) { - throw new RuntimeException(e); - } catch (ObjectNotFoundException e) { + } catch (SQLException | ObjectNotFoundException e) { throw new RuntimeException(e); } catch (DependencyException e) { throw new RuntimeException(e); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 4811fc605d..7ba2e723fd 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -71,7 +71,6 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis meta.simulationName, meta.applicationName, meta.biomodelName, - variablesCsv, BigDecimal.valueOf(ts.getBeginTimeIndex()), BigDecimal.valueOf(ts.getEndTimeIndex()), meta.serverSavedFileName, @@ -81,7 +80,12 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis meta.tSlices, meta.numChannels ); - ps.executeUpdate(); + System.out.println("Data insertion tag:"); + System.out.println(ps.executeUpdate()); + System.out.println("."); + //ps.executeUpdate(); + } catch (Exception e){ + System.out.println(e); } // 2) insert each parameter change diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index f55bb8602a..9674163d4d 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -45,7 +45,7 @@ public class ExportHistoryTable extends Table { zSlices, tSlices, numVariables}; private final Field[] insertFields = { - jobId, userRef, modelRef, exportFormat, exportDate, uri, dataId, + userRef, modelRef, exportFormat, exportDate, uri, dataId, simulationName, applicationName, biomodelName, variables, startTime, endTime, savedFileName, applicationType, nonSpatial, zSlices, tSlices, numVariables @@ -55,14 +55,14 @@ public class ExportHistoryTable extends Table { private ExportHistoryTable() { super(TABLE_NAME); - addFields(fields); + addFields(insertFields); } public String getInsertSQL() { StringJoiner cols = new StringJoiner(",", "(", ")"); for (Field f : insertFields) { - cols.add(f.getQualifiedColName()); + cols.add(f.getUnqualifiedColName()); } StringJoiner ph = new StringJoiner(",", "(", ")"); @@ -83,7 +83,6 @@ public void bindForInsert( String simName, String appName, String bioName, - String variablesCsv, BigDecimal startTimeValue, BigDecimal endTimeValue, String savedFileNameValue, @@ -104,7 +103,6 @@ public void bindForInsert( ps.setString (i++, simName); ps.setString (i++, appName); ps.setString (i++, bioName); - ps.setString (i++, variablesCsv); ps.setBigDecimal (i++, startTimeValue); ps.setBigDecimal (i++, endTimeValue); ps.setString (i++, savedFileNameValue); @@ -114,51 +112,51 @@ public void bindForInsert( ps.setInt (i++, tSlicesValue); ps.setInt (i++, numVariablesValue); } - public record ExportHistoryRecord(String jobID, long userRef, long modelRef, ExportFormat format, Timestamp date, - String uri, String dataID, String simName, String appName, String bioName, - BigDecimal startTime, BigDecimal endTime, String savedFile, String appType, - boolean nonSpatial, int zSlices, int tSlices, int numVars) { - } - - public ExportHistoryRecord getExportHistoryRecord(ResultSet rset, ExportHistoryRecord exportHistoryRecord) throws SQLException, SQLException { - - long userRef = rset.getLong((int) exportHistoryRecord.userRef); - long modelRef = rset.getLong((int) exportHistoryRecord.modelRef); - - // enums & timestamps - ExportFormat fmt = ExportFormat.valueOf(rset.getString(exportFormat.toString())); - Timestamp date = rset.getTimestamp(exportDate.toString()); - - // strings - String jobId = rset.getString(exportHistoryRecord.jobID); - String uriVal = rset.getString(uri.toString()); - String dataIdVal = rset.getString(dataId.toString()); - String simNameVal = rset.getString(simulationName.toString()); - String appNameVal = rset.getString(applicationName.toString()); - String bioNameVal = rset.getString(biomodelName.toString()); - - // text array of variables - Array sqlArr = rset.getArray(variables.toString()); - - // numeric ranges - BigDecimal startBt = rset.getBigDecimal(startTime.toString()); - BigDecimal endBt = rset.getBigDecimal(endTime.toString()); - - // more strings & flags - String savedFileVal = rset.getString(savedFileName.toString()); - String appTypeVal = rset.getString(applicationType.toString()); - boolean nonSp = rset.getBoolean(nonSpatial.toString()); - int zS = rset.getInt(zSlices.toString()); - int tS = rset.getInt(tSlices.toString()); - int numV = rset.getInt(numVariables.toString()); - - - - return new ExportHistoryRecord( - jobId, userRef, modelRef, fmt, date, - uriVal, dataIdVal, simNameVal, appNameVal, bioNameVal, - startBt, endBt, savedFileVal, appTypeVal, - nonSp, zS, tS, numV - ); - } +// public record ExportHistoryRecord(String jobID, long userRef, long modelRef, ExportFormat format, Timestamp date, +// String uri, String dataID, String simName, String appName, String bioName, +// BigDecimal startTime, BigDecimal endTime, String savedFile, String appType, +// boolean nonSpatial, int zSlices, int tSlices, int numVars) { +// } +// +// public ExportHistoryRecord getExportHistoryRecord(ResultSet rset, ExportHistoryRecord exportHistoryRecord) throws SQLException, SQLException { +// +// long userRef = rset.getLong((int) exportHistoryRecord.userRef); +// long modelRef = rset.getLong((int) exportHistoryRecord.modelRef); +// +// // enums & timestamps +// ExportFormat fmt = ExportFormat.valueOf(rset.getString(exportFormat.toString())); +// Timestamp date = rset.getTimestamp(exportDate.toString()); +// +// // strings +// String jobId = rset.getString(exportHistoryRecord.jobID); +// String uriVal = rset.getString(uri.toString()); +// String dataIdVal = rset.getString(dataId.toString()); +// String simNameVal = rset.getString(simulationName.toString()); +// String appNameVal = rset.getString(applicationName.toString()); +// String bioNameVal = rset.getString(biomodelName.toString()); +// +// // text array of variables +// Array sqlArr = rset.getArray(variables.toString()); +// +// // numeric ranges +// BigDecimal startBt = rset.getBigDecimal(startTime.toString()); +// BigDecimal endBt = rset.getBigDecimal(endTime.toString()); +// +// // more strings & flags +// String savedFileVal = rset.getString(savedFileName.toString()); +// String appTypeVal = rset.getString(applicationType.toString()); +// boolean nonSp = rset.getBoolean(nonSpatial.toString()); +// int zS = rset.getInt(zSlices.toString()); +// int tS = rset.getInt(tSlices.toString()); +// int numV = rset.getInt(numVariables.toString()); +// +// +// +// return new ExportHistoryRecord( +// jobId, userRef, modelRef, fmt, date, +// uriVal, dataIdVal, simNameVal, appNameVal, bioNameVal, +// startBt, endBt, savedFileVal, appTypeVal, +// nonSp, zS, tS, numV +// ); +// } } From 1767e5f7942973885546298ad7b1b6b3b565a7ad Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 15 Aug 2025 14:29:30 -0400 Subject: [PATCH 14/65] Fixed Strange Time Error --- .../main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java | 2 -- .../main/java/cbit/vcell/modeldb/ExportHistoryTable.java | 6 +++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 7ba2e723fd..ee9cf7d81d 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -84,8 +84,6 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis System.out.println(ps.executeUpdate()); System.out.println("."); //ps.executeUpdate(); - } catch (Exception e){ - System.out.println(e); } // 2) insert each parameter change diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 9674163d4d..0205a9af08 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -6,6 +6,10 @@ import java.math.BigDecimal; import java.sql.*; +import java.time.Instant; +import java.time.LocalTime; +import java.util.HashMap; +import java.util.Map; import java.util.StringJoiner; public class ExportHistoryTable extends Table { @@ -45,7 +49,7 @@ public class ExportHistoryTable extends Table { zSlices, tSlices, numVariables}; private final Field[] insertFields = { - userRef, modelRef, exportFormat, exportDate, uri, dataId, + jobId, userRef, modelRef, exportFormat, exportDate, uri, dataId, simulationName, applicationName, biomodelName, variables, startTime, endTime, savedFileName, applicationType, nonSpatial, zSlices, tSlices, numVariables From 05d6e8320b0497037e4529c4c8484e04134dc906 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Tue, 19 Aug 2025 14:45:09 -0400 Subject: [PATCH 15/65] Fixed sql injections (all fields inserted with pk null exception), WIP --- .../org/vcell/restq/ExportHistoryTest.java | 12 +++++--- .../java/cbit/vcell/modeldb/DBTopLevel.java | 2 +- .../vcell/modeldb/ExportHistoryDBDriver.java | 29 ++++++++++--------- .../vcell/modeldb/ExportHistoryTable.java | 9 ++++++ 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index 4e6f0d8f05..c3c8cdbcea 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -155,7 +155,8 @@ public void testAddExportHistory() { now, "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", exportSpecs - ) + ), + agroalConnectionFactory.getKeyFactory() ); try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { @@ -188,7 +189,8 @@ public void testDeleteExportHistory() throws SQLException { driver.addExportHistory(conn, user, - new ExportHistoryDBDriver.ExportHistory(7L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "to-delete", exportSpecs) + new ExportHistoryDBDriver.ExportHistory(7L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "to-delete", exportSpecs), + agroalConnectionFactory.getKeyFactory() ); @@ -230,10 +232,12 @@ public void testGetExportHistory() throws SQLException, DataAccessException { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); driver.addExportHistory(conn, user, - new ExportHistoryDBDriver.ExportHistory(100L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri100", exportSpecs) + new ExportHistoryDBDriver.ExportHistory(100L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri100", exportSpecs), + agroalConnectionFactory.getKeyFactory() ); driver.addExportHistory(conn, user, - new ExportHistoryDBDriver.ExportHistory(101L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri101", exportSpecs) + new ExportHistoryDBDriver.ExportHistory(101L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri101", exportSpecs), + agroalConnectionFactory.getKeyFactory() ); int count = 0; diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index d86eed7b1e..9725b52569 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -2260,7 +2260,7 @@ public void insertExportHistory(User user, ExportHistoryDBDriver.ExportHistory e Object lock = new Object(); Connection con = conFactory.getConnection(lock); try { - exportHistoryDB.addExportHistory(con, user, exportHistoryValues); + exportHistoryDB.addExportHistory(con, user, exportHistoryValues, conFactory.getKeyFactory()); } catch (Throwable e) { lg.error(e.getMessage(),e); try { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index ee9cf7d81d..5b337cbd35 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -12,6 +12,7 @@ import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; import org.vcell.util.document.VCDataIdentifier; +import org.vcell.util.document.VersionableType; import java.math.BigDecimal; import java.sql.*; @@ -19,7 +20,7 @@ import java.util.HashMap; import java.util.StringJoiner; -public class ExportHistoryDBDriver{ +public class ExportHistoryDBDriver { public static final ExportHistoryTable exportHistoryTable = ExportHistoryTable.table; public static final ModelParameterValuesTable modelParameterValuesTable = ModelParameterValuesTable.table; public static final BioModelTable bioModelTable = BioModelTable.table; @@ -47,7 +48,7 @@ public record ExportHistory( ExportSpecs exportSpecs ){} - public void addExportHistory(Connection conn, User user, ExportHistory exportHistory) + public void addExportHistory(Connection conn, User user, ExportHistory exportHistory, KeyFactory keyFactory) throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { ExportSpecs specs = exportHistory.exportSpecs; @@ -61,6 +62,7 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis String ehSQL = ExportHistoryTable.table.getInsertSQL(); try (PreparedStatement ps = conn.prepareStatement(ehSQL)) { ExportHistoryTable.table.bindForInsert(ps, + keyFactory.getNewKey(conn), exportHistory.jobID, Long.parseLong(user.getID().toString()), exportHistory.modelRef, @@ -71,6 +73,7 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis meta.simulationName, meta.applicationName, meta.biomodelName, + conn.createArrayOf("VARCHAR", exportHistory.exportSpecs().getVariableSpecs().getVariableNames()), BigDecimal.valueOf(ts.getBeginTimeIndex()), BigDecimal.valueOf(ts.getEndTimeIndex()), meta.serverSavedFileName, @@ -93,8 +96,8 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis String[] parts = entry.split(":"); if (parts.length == 3) { ModelParameterValuesTable.table.bindForInsert(ps2, - // note: you need the export_id FK—assumes you have it from a sequence - exportHistory.jobID, // if your PK is the jobID, else use the returned PK + + exportHistory.jobID, Long.parseLong(user.getID().toString()), exportHistory.modelRef, parts[0], @@ -173,17 +176,17 @@ public static void main(String[] args) throws SQLException, PermissionException, exportSpecs.setExportMetaData(meta); - ExportHistoryDBDriver.ExportHistory history = new ExportHistoryDBDriver.ExportHistory( - /*jobID=*/ 1, - /*modelRef=*/ 2, - /*format=*/ ExportFormat.N5, - /*date=*/ testExportDate, - /*uri=*/ "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", - /*specs=*/ exportSpecs - ); +// ExportHistoryDBDriver.ExportHistory history = new ExportHistoryDBDriver.ExportHistory( +// /*jobID=*/ 1, +// /*modelRef=*/ 2, +// /*format=*/ ExportFormat.N5, +// /*date=*/ testExportDate, +// /*uri=*/ "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", +// /*specs=*/ exportSpecs +// ); - dbDriver.addExportHistory(connection, user, history); + //dbDriver.addExportHistory(connection, user, history); System.out.println("=== Test get before deletion ==="); try (ResultSet rs = dbDriver.getExportHistoryForUser(connection, user)) { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 0205a9af08..42547bfff9 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -3,6 +3,8 @@ import cbit.sql.Field; import cbit.sql.Table; import cbit.vcell.export.server.ExportFormat; +import org.vcell.db.KeyFactory; +import org.vcell.util.document.KeyValue; import java.math.BigDecimal; import java.sql.*; @@ -15,6 +17,8 @@ public class ExportHistoryTable extends Table { private static final String TABLE_NAME = "vc_model_export_history"; + public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); + public final Field jobId = new Field("job_id", Field.SQLDataType.varchar_50, "NOT NULL"); public final Field userRef = new Field("user_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + UserTable.REF_TYPE); @@ -75,8 +79,10 @@ public String getInsertSQL() { } return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString(); } + public void bindForInsert( PreparedStatement ps, + KeyValue key, long jobIdValue, long userRefValue, long modelRefValue, @@ -87,6 +93,7 @@ public void bindForInsert( String simName, String appName, String bioName, + Array variables, BigDecimal startTimeValue, BigDecimal endTimeValue, String savedFileNameValue, @@ -107,6 +114,7 @@ public void bindForInsert( ps.setString (i++, simName); ps.setString (i++, appName); ps.setString (i++, bioName); + ps.setArray (i++, variables); ps.setBigDecimal (i++, startTimeValue); ps.setBigDecimal (i++, endTimeValue); ps.setString (i++, savedFileNameValue); @@ -115,6 +123,7 @@ public void bindForInsert( ps.setInt (i++, zSlicesValue); ps.setInt (i++, tSlicesValue); ps.setInt (i++, numVariablesValue); + } // public record ExportHistoryRecord(String jobID, long userRef, long modelRef, ExportFormat format, Timestamp date, // String uri, String dataID, String simName, String appName, String bioName, From a323f85e3d0e4a8fe0fb92e4c22c4569a54c334c Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Thu, 21 Aug 2025 02:59:28 -0400 Subject: [PATCH 16/65] Added Primary Key --- .../vcell/modeldb/ExportHistoryDBDriver.java | 3 +-- .../cbit/vcell/modeldb/ExportHistoryTable.java | 17 +++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 5b337cbd35..298a902f4f 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -59,10 +59,9 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis String variablesCsv = String.join(",", vars); // 1) insert into vc_model_export_history - String ehSQL = ExportHistoryTable.table.getInsertSQL(); + String ehSQL = ExportHistoryTable.table.getInsertSQL(keyFactory.getNewKey(conn)); try (PreparedStatement ps = conn.prepareStatement(ehSQL)) { ExportHistoryTable.table.bindForInsert(ps, - keyFactory.getNewKey(conn), exportHistory.jobID, Long.parseLong(user.getID().toString()), exportHistory.modelRef, diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 42547bfff9..18b9a59384 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -17,7 +17,7 @@ public class ExportHistoryTable extends Table { private static final String TABLE_NAME = "vc_model_export_history"; - public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); + // public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); public final Field jobId = new Field("job_id", Field.SQLDataType.varchar_50, "NOT NULL"); @@ -47,12 +47,13 @@ public class ExportHistoryTable extends Table { //public final Field insertDate = new Field("insert_date", Field.SQLDataType.date, "NOT NULL DEFAULT CURRENT_TIMESTAMP"); - private final Field fields[] = {jobId, userRef, modelRef, exportFormat, exportDate, uri, - dataId, simulationName, applicationName, biomodelName, variables, - startTime, endTime, savedFileName, applicationType, nonSpatial, - zSlices, tSlices, numVariables}; +// private final Field fields[] = {jobId, userRef, modelRef, exportFormat, exportDate, uri, +// dataId, simulationName, applicationName, biomodelName, variables, +// startTime, endTime, savedFileName, applicationType, nonSpatial, +// zSlices, tSlices, numVariables}; private final Field[] insertFields = { + // note that primary key id cannot be placed in fields (will causes class initialization error), jobId, userRef, modelRef, exportFormat, exportDate, uri, dataId, simulationName, applicationName, biomodelName, variables, startTime, endTime, savedFileName, applicationType, nonSpatial, @@ -66,7 +67,7 @@ private ExportHistoryTable() { addFields(insertFields); } - public String getInsertSQL() { + public String getInsertSQL(KeyValue key) { StringJoiner cols = new StringJoiner(",", "(", ")"); for (Field f : insertFields) { @@ -77,12 +78,11 @@ public String getInsertSQL() { for (int i = 0; i < insertFields.length; i++) { ph.add("?"); } - return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString(); + return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString() + key; } public void bindForInsert( PreparedStatement ps, - KeyValue key, long jobIdValue, long userRefValue, long modelRefValue, @@ -104,6 +104,7 @@ public void bindForInsert( int numVariablesValue ) throws SQLException { int i = 1; + // ps.setInt (i++, Integer.parseInt(key.toString())); ps.setLong (i++, jobIdValue); ps.setLong (i++, userRefValue); ps.setLong (i++, modelRefValue); From 37481788fdfbc1b84f4bf007165c4b9ab5ea21bd Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 21 Aug 2025 11:18:34 -0400 Subject: [PATCH 17/65] Properly Insert Primary Key --- .../vcell/modeldb/ExportHistoryDBDriver.java | 4 ++- .../vcell/modeldb/ExportHistoryTable.java | 36 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 298a902f4f..65c057d23f 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -59,9 +59,11 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis String variablesCsv = String.join(",", vars); // 1) insert into vc_model_export_history - String ehSQL = ExportHistoryTable.table.getInsertSQL(keyFactory.getNewKey(conn)); + String ehSQL = ExportHistoryTable.table.getInsertSQL(); + KeyValue keyValue = keyFactory.getNewKey(conn); try (PreparedStatement ps = conn.prepareStatement(ehSQL)) { ExportHistoryTable.table.bindForInsert(ps, + keyValue, exportHistory.jobID, Long.parseLong(user.getID().toString()), exportHistory.modelRef, diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 18b9a59384..3f492b8466 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -3,15 +3,10 @@ import cbit.sql.Field; import cbit.sql.Table; import cbit.vcell.export.server.ExportFormat; -import org.vcell.db.KeyFactory; import org.vcell.util.document.KeyValue; import java.math.BigDecimal; import java.sql.*; -import java.time.Instant; -import java.time.LocalTime; -import java.util.HashMap; -import java.util.Map; import java.util.StringJoiner; public class ExportHistoryTable extends Table { @@ -52,37 +47,40 @@ public class ExportHistoryTable extends Table { // startTime, endTime, savedFileName, applicationType, nonSpatial, // zSlices, tSlices, numVariables}; - private final Field[] insertFields = { - // note that primary key id cannot be placed in fields (will causes class initialization error), - jobId, userRef, modelRef, exportFormat, exportDate, uri, dataId, - simulationName, applicationName, biomodelName, variables, - startTime, endTime, savedFileName, applicationType, nonSpatial, - zSlices, tSlices, numVariables - }; - public static final ExportHistoryTable table = new ExportHistoryTable(); private ExportHistoryTable() { super(TABLE_NAME); - addFields(insertFields); + // Minus id, which is added by the table abstract class + // note that primary key id cannot be placed in fields (will causes class initialization error), + Field[] customFields = { + // note that primary key id cannot be placed in fields (will causes class initialization error), + jobId, userRef, modelRef, exportFormat, exportDate, uri, dataId, + simulationName, applicationName, biomodelName, variables, + startTime, endTime, savedFileName, applicationType, nonSpatial, + zSlices, tSlices, numVariables + }; + addFields(customFields); } - public String getInsertSQL(KeyValue key) { + public String getInsertSQL() { StringJoiner cols = new StringJoiner(",", "(", ")"); - for (Field f : insertFields) { + Field[] fieldsToInsert = getFields(); + for (Field f : fieldsToInsert) { cols.add(f.getUnqualifiedColName()); } StringJoiner ph = new StringJoiner(",", "(", ")"); - for (int i = 0; i < insertFields.length; i++) { + for (int i = 0; i < fieldsToInsert.length; i++) { ph.add("?"); } - return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString() + key; + return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString(); } public void bindForInsert( PreparedStatement ps, + KeyValue keyValue, long jobIdValue, long userRefValue, long modelRefValue, @@ -104,7 +102,7 @@ public void bindForInsert( int numVariablesValue ) throws SQLException { int i = 1; - // ps.setInt (i++, Integer.parseInt(key.toString())); + ps.setInt (i++, Integer.parseInt(keyValue.toString())); ps.setLong (i++, jobIdValue); ps.setLong (i++, userRefValue); ps.setLong (i++, modelRefValue); From e3554b0a5abfe193cc350c1af9928e5d4f11c730 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Thu, 21 Aug 2025 12:08:05 -0400 Subject: [PATCH 18/65] Removed duplicate deletion in test --- .../test/java/org/vcell/restq/ExportHistoryTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index c3c8cdbcea..47f6c1d096 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -200,12 +200,12 @@ public void testDeleteExportHistory() throws SQLException { } - driver.deleteExportHistory(conn, exportSpecs); +// driver.deleteExportHistory(conn, exportSpecs); - try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { - Assertions.assertFalse(rs.next()); - Assertions.assertNotEquals("to-delete", rs.getString("uri")); - } +// try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { +// Assertions.assertNotEquals("to-delete", rs.getString("uri")); +// Assertions.assertFalse(rs.next()); +// } driver.deleteExportHistory(conn, exportSpecs); From 5736315ef387c879d8ae3fd960f3e9cc443aaf75 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Thu, 21 Aug 2025 20:33:51 -0400 Subject: [PATCH 19/65] Added export history to database in export service --- .../export/server/ExportServiceImpl.java | 218 ++++++++++-------- 1 file changed, 116 insertions(+), 102 deletions(-) diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java index 48ab8ed5c4..bd68591234 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java @@ -27,6 +27,9 @@ import cbit.rmi.event.ExportEventController; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.vcell.db.ConnectionFactory; +import org.vcell.db.DatabaseSyntax; +import org.vcell.db.KeyFactory; import org.vcell.util.ClientTaskStatusSupport; import org.vcell.util.DataAccessException; import org.vcell.util.UserCancelException; @@ -40,6 +43,9 @@ import cbit.vcell.simdata.DataServerImpl; import cbit.vcell.simdata.OutputContext; import cbit.vcell.solver.VCSimulationDataIdentifier; +import org.vcell.restq.db.AgroalConnectionFactory; +import cbit.vcell.modeldb.ExportHistoryDBDriver; + /** * This type was created in VisualAge. @@ -53,6 +59,8 @@ public ExportEventController getEventController() { return eventController; } + @Inject + AgroalConnectionFactory agroalConnectionFactory; public ExportServiceImpl() { } @@ -63,12 +71,13 @@ public ExportEvent makeRemoteFile(OutputContext outputContext,User user, DataSer } + /** * Insert the method's description here. * Creation date: (4/1/2001 11:20:45 AM) * @deprecated */ -protected ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, String format, String location,ExportSpecs exportSpecs) { +protected ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, String format, String location,ExportSpecs exportSpecs) throws SQLException, DataAccessException { User user = null; Object object = jobRequestIDs.get(new Long(jobID)); if (object != null) { @@ -93,16 +102,21 @@ protected ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, St event.setHumanReadableExportData(exportSpecs.getHumanReadableExportData()); assert user != null; + try (Connection conn = agroalConnectionFactory.getConnection(null)) { + exportHistoryDBDriver.addExportHistory(conn, vcdID.getOwner(), new ExportHistoryDBDriver.ExportHistory(jobID, 1, exportSpecs.getFormat(), new Timestamp(System.currentTimeMillis()), location, exportSpecs), agroalConnectionFactory.getKeyFactory()); + + } + -exportToDB( - jobID, - Long.parseLong(user.getID().toString()), - Long.parseLong(vcdID.getOwner().getID().toString()), - format, - new Timestamp(System.currentTimeMillis()), - location, - exportSpecs - ); +//exportToDB( +// jobID, +// Long.parseLong(user.getID().toString()), +// Long.parseLong(vcdID.getOwner().getID().toString()), +// format, +// new Timestamp(System.currentTimeMillis()), +// location, +// exportSpecs +// ); fireExportEvent(event); return event; public ExportEvent makeRemoteFile(OutputContext outputContext, User user, DataServerImpl dataServer, ExportSpecs exportSpecs, boolean zip, ClientTaskStatusSupport clientTaskStatusSupport)throws DataAccessException { @@ -396,95 +410,95 @@ private static ExportEvent makeRemoteN5File(String fileFormat, String fileName, } -private void exportToDB(long jobID, - long userRef, - long modelRef, - String exportFormat, - Timestamp exportDate, - String uri, - ExportSpecs exportSpecs) { - Connection conn = null; - PreparedStatement ps = null; - PreparedStatement psParam = null; - ResultSet rsSeq = null; - boolean passed; - try { - conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); - - - String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server - "INSERT INTO vc_model_export_history (" + - "id, job_id, user_ref, model_ref, export_format, export_date, uri," + - "data_id, simulation_name, application_name, biomodel_name, variables," + - "start_time, end_time, saved_file_name, application_type, non_spatial," + - "z_slices, t_slices, num_variables" + - ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; - ps = conn.prepareStatement(vcmExpHiSQL); - - HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); - TimeSpecs ts = exportSpecs.getTimeSpecs(); - String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); - - String timeRange = ts.toString(); - String[] time_parts = timeRange.split("/"); - BigDecimal startTime = new BigDecimal(time_parts[0]); - BigDecimal endTime = new BigDecimal(time_parts[1]); - - - ps.setLong (2, jobID); - ps.setLong (3, userRef); - ps.setLong (4, modelRef); - ps.setString (5, exportFormat); - ps.setTimestamp (6, exportDate); - ps.setString (7, uri); - ps.setString (8, exportSpecs.getVCDataIdentifier().getID()); - ps.setString (9, meta.simulationName); - ps.setString (10, meta.applicationName); - ps.setString (11, meta.biomodelName); - ps.setArray (12, conn.createArrayOf("text", vars)); - ps.setBigDecimal (13, startTime); - ps.setBigDecimal (14, endTime); - ps.setString (15, meta.serverSavedFileName); - ps.setString (16, meta.applicationType); - ps.setBoolean (17, meta.nonSpatial); - ps.setInt (18, meta.zSlices); - ps.setInt (19, meta.tSlices); - ps.setInt (20, meta.numChannels); - ps.executeUpdate(); - - - String vcmExpHisPVSQL = // SQL statement for inserting into vc_model_parameter_value table in VCell server - "INSERT INTO vc_model_parameter_values (" + - "export_id, user_ref, model_ref, parameter_name," + - "parameter_original, parameter_changed" + - ") VALUES (?,?,?,?,?,?)"; - psParam = conn.prepareStatement(vcmExpHisPVSQL); - - - for (String entry : meta.differentParameterValues) { - String[] parts = entry.split(":"); - if (parts.length == 3) { - //psParam.setLong (1, historyId); - psParam.setLong (2, userRef); - psParam.setLong (3, modelRef); - psParam.setString (4, parts[0]); - psParam.setBigDecimal (5, new BigDecimal(parts[1])); - psParam.setBigDecimal (6, new BigDecimal(parts[2])); - psParam.addBatch(); - } - } - psParam.executeBatch(); - } - catch(SQLException e){ - lg.error("Error exporting to database",e); - } - finally { - try{ if(rsSeq !=null) rsSeq.close(); }catch(Exception ign){} - try{ if(psParam !=null) psParam.close(); }catch(Exception ign){} - try{ if(ps !=null) ps.close(); }catch(Exception ign){} - try{ if(conn !=null) conn.close(); }catch(Exception ign){} - } -} - - -} +//private void exportToDB(long jobID, +// long userRef, +// long modelRef, +// String exportFormat, +// Timestamp exportDate, +// String uri, +// ExportSpecs exportSpecs) { +// Connection conn = null; +// PreparedStatement ps = null; +// PreparedStatement psParam = null; +// ResultSet rsSeq = null; +// boolean passed; +// try { +// conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); +// +// +// String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server +// "INSERT INTO vc_model_export_history (" + +// "id, job_id, user_ref, model_ref, export_format, export_date, uri," + +// "data_id, simulation_name, application_name, biomodel_name, variables," + +// "start_time, end_time, saved_file_name, application_type, non_spatial," + +// "z_slices, t_slices, num_variables" + +// ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; +// ps = conn.prepareStatement(vcmExpHiSQL); +// +// HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); +// TimeSpecs ts = exportSpecs.getTimeSpecs(); +// String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); +// +// String timeRange = ts.toString(); +// String[] time_parts = timeRange.split("/"); +// BigDecimal startTime = new BigDecimal(time_parts[0]); +// BigDecimal endTime = new BigDecimal(time_parts[1]); +// +// +// ps.setLong (2, jobID); +// ps.setLong (3, userRef); +// ps.setLong (4, modelRef); +// ps.setString (5, exportFormat); +// ps.setTimestamp (6, exportDate); +// ps.setString (7, uri); +// ps.setString (8, exportSpecs.getVCDataIdentifier().getID()); +// ps.setString (9, meta.simulationName); +// ps.setString (10, meta.applicationName); +// ps.setString (11, meta.biomodelName); +// ps.setArray (12, conn.createArrayOf("text", vars)); +// ps.setBigDecimal (13, startTime); +// ps.setBigDecimal (14, endTime); +// ps.setString (15, meta.serverSavedFileName); +// ps.setString (16, meta.applicationType); +// ps.setBoolean (17, meta.nonSpatial); +// ps.setInt (18, meta.zSlices); +// ps.setInt (19, meta.tSlices); +// ps.setInt (20, meta.numChannels); +// ps.executeUpdate(); +// +// +// String vcmExpHisPVSQL = // SQL statement for inserting into vc_model_parameter_value table in VCell server +// "INSERT INTO vc_model_parameter_values (" + +// "export_id, user_ref, model_ref, parameter_name," + +// "parameter_original, parameter_changed" + +// ") VALUES (?,?,?,?,?,?)"; +// psParam = conn.prepareStatement(vcmExpHisPVSQL); +// +// +// for (String entry : meta.differentParameterValues) { +// String[] parts = entry.split(":"); +// if (parts.length == 3) { +// //psParam.setLong (1, historyId); +// psParam.setLong (2, userRef); +// psParam.setLong (3, modelRef); +// psParam.setString (4, parts[0]); +// psParam.setBigDecimal (5, new BigDecimal(parts[1])); +// psParam.setBigDecimal (6, new BigDecimal(parts[2])); +// psParam.addBatch(); +// } +// } +// psParam.executeBatch(); +// } +// catch(SQLException e){ +// lg.error("Error exporting to database",e); +// } +// finally { +// try{ if(rsSeq !=null) rsSeq.close(); }catch(Exception ign){} +// try{ if(psParam !=null) psParam.close(); }catch(Exception ign){} +// try{ if(ps !=null) ps.close(); }catch(Exception ign){} +// try{ if(conn !=null) conn.close(); }catch(Exception ign){} +// } +//} +// +// +//} From a8e02db4a11cd775ad65968aa0bbd4cac47d4eb7 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Thu, 21 Aug 2025 20:41:30 -0400 Subject: [PATCH 20/65] Added export history database injection to export service --- vcell-core/pom.xml | 14 +++++++++++++- .../vcell/export/server/ExportServiceImpl.java | 17 +++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/vcell-core/pom.xml b/vcell-core/pom.xml index 78a83a6373..9c335d19e2 100644 --- a/vcell-core/pom.xml +++ b/vcell-core/pom.xml @@ -692,9 +692,21 @@ microprofile-openapi-api ${microprofile-openapi.version} + + org.vcell + vcell-server + 0.0.1-SNAPSHOT + compile + + + org.vcell + vcell-rest + 1.0.0-SNAPSHOT + compile + - + diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java index bd68591234..36d2011c46 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java @@ -43,8 +43,9 @@ import cbit.vcell.simdata.DataServerImpl; import cbit.vcell.simdata.OutputContext; import cbit.vcell.solver.VCSimulationDataIdentifier; -import org.vcell.restq.db.AgroalConnectionFactory; import cbit.vcell.modeldb.ExportHistoryDBDriver; +import org.vcell.restq.db.AgroalConnectionFactory; + /** @@ -59,6 +60,8 @@ public ExportEventController getEventController() { return eventController; } + + @Inject AgroalConnectionFactory agroalConnectionFactory; @@ -94,7 +97,7 @@ protected ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, St throw new RuntimeException("unexpected VCDataIdentifier"); } ExportEvent event = new ExportEvent( - this, jobID, user, vcdID.getID(), dataKey, ExportEvent.EXPORT_COMPLETE, + this, jobID, user, vcdID.getID(), dataKey, ExportEvent.EXPORT_COMPLETE, format, location, null, timeSpecs, varSpecs); event.setHumanReadableExportData(exportSpecs != null ? exportSpecs.getHumanReadableExportData() : null); @@ -102,6 +105,8 @@ protected ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, St event.setHumanReadableExportData(exportSpecs.getHumanReadableExportData()); assert user != null; + + try (Connection conn = agroalConnectionFactory.getConnection(null)) { exportHistoryDBDriver.addExportHistory(conn, vcdID.getOwner(), new ExportHistoryDBDriver.ExportHistory(jobID, 1, exportSpecs.getFormat(), new Timestamp(System.currentTimeMillis()), location, exportSpecs), agroalConnectionFactory.getKeyFactory()); @@ -263,7 +268,7 @@ private static ExportEvent makeRemoteFile(String fileFormat, String exportBaseDi if (nrrdInfos[i].isHasData()) { // nrrdInfo 'header' file contains either just the header or both the header and data together ZipEntry zipEntry = new ZipEntry(nrrdInfos[i].getCanonicalFilename((nrrdInfos[i].isSeparateHeader()?true:false))); - zipOut.putNextEntry(zipEntry); + zipOut.putNextEntry(zipEntry); fileDataContainerManager.writeAndFlush(nrrdInfos[i].getHeaderFileID(), zipOut); if (nrrdInfos[i].isSeparateHeader()) { // The data was not saved with the 'header' file so save it separately @@ -281,7 +286,7 @@ private static ExportEvent makeRemoteFile(String fileFormat, String exportBaseDi } finally { zipOut.close(); } - + if (exportValid) { if (lg.isTraceEnabled()) lg.trace("ExportServiceImpl.makeRemoteFile(): Successfully exported to file: " + zipFile.getName()); URL url = new URL(exportBaseURL + zipFile.getName()); @@ -326,7 +331,7 @@ private static ExportEvent saveResultsToRemoteFile(String fileFormat, String exp } } zipOut.close(); - + if (exportValid) { if (lg.isTraceEnabled()) lg.trace("ExportServiceImpl.makeRemoteFile(): Successfully exported to file: " + zipFile.getName()); URL url = new URL(exportBaseURL + zipFile.getName()); @@ -362,7 +367,7 @@ private static ExportEvent makeRemoteFile_Unzipped(String fileFormat, String exp //if there are more export outputs, loops through the second till the last. for (int i=1;i Date: Mon, 28 Jul 2025 10:09:28 -0400 Subject: [PATCH 21/65] DTO Updates --- .../services/Exports/ExportStatusCreator.java | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportStatusCreator.java diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportStatusCreator.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportStatusCreator.java new file mode 100644 index 0000000000..df1711ff71 --- /dev/null +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportStatusCreator.java @@ -0,0 +1,163 @@ +package org.vcell.restq.services.Exports; + +import cbit.rmi.event.ExportEvent; +import cbit.rmi.event.ExportListener; +import cbit.rmi.event.ExportStatusEventCreator; +import cbit.vcell.export.server.ExportSpecs; +import cbit.vcell.export.server.ExportSpecss; +import cbit.vcell.export.server.TimeSpecs; +import cbit.vcell.export.server.VariableSpecs; +import cbit.vcell.solver.VCSimulationDataIdentifier; +import io.smallrye.mutiny.Multi; +import io.smallrye.mutiny.helpers.MultiEmitterProcessor; +import jakarta.enterprise.context.ApplicationScoped; +import org.vcell.util.ObjectNotFoundException; +import org.vcell.util.document.ExternalDataIdentifier; +import org.vcell.util.document.KeyValue; +import org.vcell.util.document.User; +import org.vcell.util.document.VCDataIdentifier; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +@ApplicationScoped +public class ExportStatusCreator implements ExportStatusEventCreator { + private final ConcurrentHashMap jobRequestToUser = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> listeners = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> mostRecentExportEvents = new ConcurrentHashMap<>(); // TODO: Clean out this set + + + protected ExportSpecs exportExists(ExportSpecs exportSpecs) { + // Call DB for export history and check if it exists. Store in cache if it exists for future requests. + return exportSpecs; + } + + public ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, String format, String location, ExportSpecs exportSpecs) { + User user = jobRequestToUser.get(jobID); + String key = entryKey(user, jobID); + + TimeSpecs timeSpecs = (exportSpecs!=null)?exportSpecs.getTimeSpecs():(null); + VariableSpecs varSpecs = (exportSpecs!=null)?exportSpecs.getVariableSpecs():(null); + final KeyValue dataKey; + if (vcdID instanceof VCSimulationDataIdentifier) { + dataKey = ((VCSimulationDataIdentifier)vcdID).getSimulationKey(); + }else if (vcdID instanceof ExternalDataIdentifier) { + dataKey = ((ExternalDataIdentifier)vcdID).getSimulationKey(); + }else { + throw new RuntimeException("unexpected VCDataIdentifier"); + } + ExportEvent event = new ExportEvent( + this, jobID, user, vcdID.getID(), dataKey, ExportSpecss.ExportProgressType.EXPORT_COMPLETE, + format, location, null, timeSpecs, varSpecs); + event.setHumanReadableExportData(exportSpecs != null ? exportSpecs.getHumanReadableExportData() : null); + event.setHumanReadableExportData(exportSpecs.getHumanReadableExportData()); + + + synchronized (this){ + if (!listeners.containsKey(key)) { + throw new RuntimeException("Did not find entry for user " + user.getName() + " and job id " + jobID); + } + listeners.get(key).onNext(event); + listeners.get(key).complete(); + replaceSetEntry(user, event); + removeServerExportListener(user, jobID); + jobRequestToUser.remove(jobID); + } + + return event; + } + + public synchronized void addExportListener(ExportListener listener) { + throw new IllegalCallerException("addExportListener not implemented for the server"); + } + + public synchronized Multi getUsersExportStatus(User user, long exportJobID) throws ObjectNotFoundException { + String key = entryKey(user, exportJobID); + if (!listeners.containsKey(key)) { + throw new ObjectNotFoundException("Did not find entry for user " + user.getName() + " and job id " + exportJobID); + } + return listeners.get(key).toMulti(); + } + + public synchronized Set getMostRecentExportStatus (User user) throws ObjectNotFoundException { + if (!mostRecentExportEvents.containsKey(user)) { + throw new ObjectNotFoundException("Did not find entry for user " + user.getName()); + } + return mostRecentExportEvents.get(user); + } + + public synchronized void addServerExportListener(User user, long exportJobID){ + MultiEmitterProcessor emitter = MultiEmitterProcessor.create(); + String key = entryKey(user, exportJobID); + listeners.put(key, emitter); + jobRequestToUser.put(exportJobID, user); + ExportEvent event = new ExportEvent( + this, exportJobID, user, "", null, ExportSpecss.ExportProgressType.EXPORT_ASSEMBLING, + "", "", 0.0, null, null); + if (!mostRecentExportEvents.containsKey(user)) { + mostRecentExportEvents.put(user, new HashSet<>()); + } + mostRecentExportEvents.get(user).add(event); + } + + public void fireExportAssembling(long jobID, VCDataIdentifier vcdID, String format) { + User user = jobRequestToUser.get(jobID); + ExportEvent event = new ExportEvent(this, jobID, user, vcdID, ExportSpecss.ExportProgressType.EXPORT_ASSEMBLING, format, null, null, null, null); + fireExportEvent(event); + } + + public synchronized void fireExportEvent(ExportEvent event) { + String key = entryKey(event.getUser(), event.getJobID()); + if (!listeners.containsKey(key)){ + throw new RuntimeException("Did not find entry for user " + event.getUser().getName() + " and job id " + event.getJobID()); + } + MultiEmitterProcessor listener = listeners.get(event.getUser().getName() + event.getJobID()); + listener.onNext(event); + replaceSetEntry(event.getUser(), event); + } + + public synchronized void fireExportFailed(long jobID, VCDataIdentifier vcdID, String format, String message) { + User user = jobRequestToUser.get(jobID); + String key = entryKey(user, jobID); + if (!listeners.containsKey(key)) { + throw new RuntimeException("Did not find entry for user " + user.getName() + " and job id " + jobID); + } + ExportEvent event = new ExportEvent(this, jobID, user, vcdID, ExportSpecss.ExportProgressType.EXPORT_FAILURE, format, message, null, null, null); + listeners.get(key).onNext(event); + listeners.get(key).complete(); + + replaceSetEntry(user, event); + removeServerExportListener(user, jobID); + jobRequestToUser.remove(jobID); + } + + public void fireExportProgress(long jobID, VCDataIdentifier vcdID, String format, double progress) { + User user = jobRequestToUser.get(jobID); + + ExportEvent event = new ExportEvent(this, jobID, user, vcdID, ExportSpecss.ExportProgressType.EXPORT_PROGRESS, format, null, progress, null, null); + fireExportEvent(event); + } + + public void fireExportStarted(long jobID, VCDataIdentifier vcdID, String format) { + User user = jobRequestToUser.get(jobID); + + ExportEvent event = new ExportEvent(this, jobID, user, vcdID, ExportSpecss.ExportProgressType.EXPORT_START, format, null, null, null, null); + fireExportEvent(event); + } + + public void removeServerExportListener(User user, long exportJobID){ + listeners.remove(user.getName() + exportJobID); + } + + private String entryKey(User user, long jobID){ + return user.getName() + jobID; + } + + private void replaceSetEntry(User user, ExportEvent newEvent){ + mostRecentExportEvents.get(user).remove(newEvent); + mostRecentExportEvents.get(user).add(newEvent); + } +} From e31ee7839d9e37ba16d2521cdcec1aa81ab62826 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Fri, 20 Jun 2025 11:46:19 -0400 Subject: [PATCH 22/65] Added exportation to database script --- .../src/main/java/cbit/vcell/export/server/ExportSpecs.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java index 71fc18b28d..5ed3df14f1 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java @@ -10,9 +10,15 @@ package cbit.vcell.export.server; import java.io.Serializable; +import java.math.BigDecimal; +import java.sql.*; +import java.util.Arrays; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import cbit.rmi.event.ExportEvent; +import cbit.vcell.solver.MathOverrides; +import cbit.vcell.solver.Simulation; import org.vcell.util.BeanUtils; import org.vcell.util.Compare; import org.vcell.util.Range; From f0192a80090dfc22a9e66fa691758c84ff1990f9 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:49:27 -0400 Subject: [PATCH 23/65] Added export history test and updated export history key access --- .../src/main/java/org/vcell/restq/handlers/ExportResource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java index 47488a8f95..6cd734ce8b 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java +++ b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java @@ -1,5 +1,6 @@ package org.vcell.restq.handlers; +import cbit.vcell.modeldb.ExportHistoryDBDriver; import cbit.rmi.event.ExportEvent; import cbit.vcell.export.server.*; import cbit.vcell.math.Variable; From 3a167cd8c929b444ee11c56d69dab368529e158c Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:50:13 -0400 Subject: [PATCH 24/65] Fixed implementation error and added TODO --- .../vcell/restq/services/ExportService.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java b/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java new file mode 100644 index 0000000000..6673a4cac7 --- /dev/null +++ b/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java @@ -0,0 +1,31 @@ +package org.vcell.restq.services; + +import cbit.vcell.modeldb.DatabaseServerImpl; +import cbit.vcell.modeldb.ExportHistoryDBDriver; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import org.vcell.restq.db.AgroalConnectionFactory; +import org.vcell.restq.handlers.ExportResource; +import org.vcell.util.DataAccessException; +import org.vcell.util.document.User; + +@ApplicationScoped +public class ExportService { + private final DatabaseServerImpl databaseServer; + + @Inject + public ExportService(AgroalConnectionFactory connectionFactory) throws DataAccessException { + this.databaseServer = new DatabaseServerImpl(connectionFactory, connectionFactory.getKeyFactory()); + } + + + public ExportHistoryDBDriver.ExportHistory getExportHistory(User user) throws DataAccessException { + // TODO: Pipe down to DB layer + return null; + } + + public void addExportHistory(User user, ExportHistoryDBDriver.ExportHistory history) throws DataAccessException { + databaseServer.addExportHistory(user, history); + } + +} From 2569e7540a254494f4e7296c15cb5c4862fc5731 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 15 Aug 2025 14:29:30 -0400 Subject: [PATCH 25/65] Fixed Strange Time Error --- .../src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 3f492b8466..5edc1a2cdd 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -7,6 +7,10 @@ import java.math.BigDecimal; import java.sql.*; +import java.time.Instant; +import java.time.LocalTime; +import java.util.HashMap; +import java.util.Map; import java.util.StringJoiner; public class ExportHistoryTable extends Table { From 673e9aaad0ce843d46f9c800f4ff03670f60b3d7 Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Tue, 19 Aug 2025 14:45:09 -0400 Subject: [PATCH 26/65] Fixed sql injections (all fields inserted with pk null exception), WIP --- .../src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 5edc1a2cdd..02a5a00a9d 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -3,6 +3,7 @@ import cbit.sql.Field; import cbit.sql.Table; import cbit.vcell.export.server.ExportFormat; +import org.vcell.db.KeyFactory; import org.vcell.util.document.KeyValue; import java.math.BigDecimal; @@ -16,7 +17,7 @@ public class ExportHistoryTable extends Table { private static final String TABLE_NAME = "vc_model_export_history"; - // public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); + public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); public final Field jobId = new Field("job_id", Field.SQLDataType.varchar_50, "NOT NULL"); @@ -84,7 +85,7 @@ public String getInsertSQL() { public void bindForInsert( PreparedStatement ps, - KeyValue keyValue, + KeyValue key, long jobIdValue, long userRefValue, long modelRefValue, From 606fe1d9b40deb6a4dfc91dc4ce54bc1f2b9a1eb Mon Sep 17 00:00:00 2001 From: Ricky Paul <67162435+paulricky@users.noreply.github.com> Date: Thu, 21 Aug 2025 02:59:28 -0400 Subject: [PATCH 27/65] Added Primary Key --- .../main/java/cbit/vcell/modeldb/ExportHistoryTable.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 02a5a00a9d..3ddf5da534 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -17,7 +17,7 @@ public class ExportHistoryTable extends Table { private static final String TABLE_NAME = "vc_model_export_history"; - public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); + // public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); public final Field jobId = new Field("job_id", Field.SQLDataType.varchar_50, "NOT NULL"); @@ -68,7 +68,7 @@ private ExportHistoryTable() { addFields(customFields); } - public String getInsertSQL() { + public String getInsertSQL(KeyValue key) { StringJoiner cols = new StringJoiner(",", "(", ")"); Field[] fieldsToInsert = getFields(); @@ -80,12 +80,11 @@ public String getInsertSQL() { for (int i = 0; i < fieldsToInsert.length; i++) { ph.add("?"); } - return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString(); + return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString() + key; } public void bindForInsert( PreparedStatement ps, - KeyValue key, long jobIdValue, long userRefValue, long modelRefValue, From 5419ba601477351415d13606fd4cb859f767d856 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 21 Aug 2025 11:18:34 -0400 Subject: [PATCH 28/65] Properly Insert Primary Key --- .../java/cbit/vcell/modeldb/ExportHistoryTable.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 3ddf5da534..3f492b8466 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -3,15 +3,10 @@ import cbit.sql.Field; import cbit.sql.Table; import cbit.vcell.export.server.ExportFormat; -import org.vcell.db.KeyFactory; import org.vcell.util.document.KeyValue; import java.math.BigDecimal; import java.sql.*; -import java.time.Instant; -import java.time.LocalTime; -import java.util.HashMap; -import java.util.Map; import java.util.StringJoiner; public class ExportHistoryTable extends Table { @@ -68,7 +63,7 @@ private ExportHistoryTable() { addFields(customFields); } - public String getInsertSQL(KeyValue key) { + public String getInsertSQL() { StringJoiner cols = new StringJoiner(",", "(", ")"); Field[] fieldsToInsert = getFields(); @@ -80,11 +75,12 @@ public String getInsertSQL(KeyValue key) { for (int i = 0; i < fieldsToInsert.length; i++) { ph.add("?"); } - return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString() + key; + return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString(); } public void bindForInsert( PreparedStatement ps, + KeyValue keyValue, long jobIdValue, long userRefValue, long modelRefValue, From 482f419aa112c947c37a3a45774034346725bf28 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 21 Aug 2025 12:28:46 -0400 Subject: [PATCH 29/65] Remove Unwanted Changes --- .../vcell/client/data/PDEExportDataPanel.java | 8 +- .../export/server/ExportServiceImpl.java | 2 - .../cbit/vcell/export/server/ExportSpecs.java | 93 ------------------- 3 files changed, 1 insertion(+), 102 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java index c30a30e102..5b2a2dd4c3 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java @@ -45,10 +45,8 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.math.BigDecimal; import java.net.URL; import java.nio.channels.FileChannel; -import java.sql.*; import java.util.*; /** * This type was created in VisualAge. @@ -706,11 +704,7 @@ private ExportSpecs getExportSpecs() { return exportSpecs; } - - - - - private ExportSpecs.SimulationSelector createSimulationSelector(){ +private ExportSpecs.SimulationSelector createSimulationSelector(){ ExportSpecs.SimulationSelector simulationSelector = new ExportSpecs.SimulationSelector(){ diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java index 36d2011c46..e5e3102928 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java @@ -15,10 +15,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; -import java.math.BigDecimal; import java.net.MalformedURLException; import java.net.URL; -import java.sql.*; import java.util.Collection; import java.util.zip.DataFormatException; import java.util.zip.ZipEntry; diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java index 5ed3df14f1..1adf1ae1d2 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java @@ -10,8 +10,6 @@ package cbit.vcell.export.server; import java.io.Serializable; -import java.math.BigDecimal; -import java.sql.*; import java.util.Arrays; import com.fasterxml.jackson.annotation.JsonCreator; @@ -214,95 +212,4 @@ public void setExportMetaData(HumanReadableExportData humanReadableExportData){ public HumanReadableExportData getHumanReadableExportData(){ return humanReadableExportData; } - - -private void saveExportToDatabase( - ExportEvent exportEvent, - ExportSpecs exportSpecs, - long userRef, - long modelRef -) throws SQLException { - - final String INSERT_HISTORY = - "INSERT INTO vc_model_export_history (" + - " id, job_id, user_ref, model_ref, export_format, export_date, uri," + - " data_id, simulation_name, application_name, biomodel_name, variables," + - " start_time, end_time, saved_file_name, application_type, non_spatial," + - " z_slices, t_slices, num_variables" + - ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; - - final String INSERT_PARAM = - "INSERT INTO vc_model_parameter_values (" + - " export_id, user_ref, model_ref, parameter_name," + - " parameter_original, parameter_changed" + - ") VALUES (?,?,?,?,?,?)"; - - try (Connection conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); - PreparedStatement psHist = conn.prepareStatement(INSERT_HISTORY); - PreparedStatement psParam = conn.prepareStatement(INSERT_PARAM)) { - - - HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); - TimeSpecs tm = exportSpecs.getTimeSpecs(); - - // 1) vc_model_export_history - //psHist.setLong (1, iD); - psHist.setLong (2, exportEvent.getJobID()); - psHist.setLong (3, userRef); - psHist.setLong (4, modelRef); - psHist.setString (5, exportSpecs.getFormat().name()); - psHist.setTimestamp (6, new Timestamp(System.currentTimeMillis())); - psHist.setString (7, exportEvent.getLocation()); - psHist.setString (8, exportSpecs.getVCDataIdentifier().toString()); - psHist.setString (9, exportSpecs.getSimulationName()); - psHist.setString (10, meta.applicationName); - psHist.setString (11, meta.biomodelName); - - // variables → SQL text[] - String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); - Array sqlVars = conn.createArrayOf("text", vars); - psHist.setArray (12, sqlVars); - - // start/end time - String timeRange = tm.toString(); - String[] time_parts = timeRange.split("/"); - BigDecimal start = new BigDecimal(time_parts[0]); - BigDecimal end = new BigDecimal(time_parts[1]); - - - psHist.setBigDecimal (13, start); - psHist.setBigDecimal (14, end); - - psHist.setString (15, meta.serverSavedFileName); - - psHist.setString (15, meta.serverSavedFileName); - psHist.setString (16, meta.applicationType); - psHist.setBoolean (17, meta.nonSpatial); - psHist.setInt (18, meta.zSlices); - psHist.setInt (19, meta.tSlices); - psHist.setInt (20, meta.numChannels); - - psHist.executeUpdate(); - - - for (String entry : meta.differentParameterValues) { - - String[] param_parts = entry.split(","); - if (param_parts.length == 3) { - //psParam.setLong (1, iD); - psParam.setLong (2, userRef); - psParam.setLong (3, modelRef); - psParam.setString (4, (param_parts[0])); - psParam.setBigDecimal (5, new BigDecimal(param_parts[1])); - psParam.setBigDecimal (6, new BigDecimal(param_parts[2])); - psParam.addBatch(); - } - } - psParam.executeBatch(); - } -} - - - - } From e855ea203f044c9a0417580a0145b0cb7258b744 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 21 Aug 2025 12:44:02 -0400 Subject: [PATCH 30/65] Rebase Local Export History on Top of Export Branch --- .../export/server/ExportServiceImpl.java | 93 ------------------- .../org/vcell/restq/ExportHistoryTest.java | 8 +- .../java/cbit/vcell/modeldb/DBTopLevel.java | 4 +- .../vcell/modeldb/ExportHistoryDBDriver.java | 64 ------------- 4 files changed, 7 insertions(+), 162 deletions(-) diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java index e5e3102928..9abae6e5ef 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java @@ -412,96 +412,3 @@ private static ExportEvent makeRemoteN5File(String fileFormat, String fileName, } } - -//private void exportToDB(long jobID, -// long userRef, -// long modelRef, -// String exportFormat, -// Timestamp exportDate, -// String uri, -// ExportSpecs exportSpecs) { -// Connection conn = null; -// PreparedStatement ps = null; -// PreparedStatement psParam = null; -// ResultSet rsSeq = null; -// boolean passed; -// try { -// conn = DriverManager.getConnection("DB_URL", "quarkus", "quarkus"); -// -// -// String vcmExpHiSQL = // SQL statement for inserting into vc_model_export_history table in VCell server -// "INSERT INTO vc_model_export_history (" + -// "id, job_id, user_ref, model_ref, export_format, export_date, uri," + -// "data_id, simulation_name, application_name, biomodel_name, variables," + -// "start_time, end_time, saved_file_name, application_type, non_spatial," + -// "z_slices, t_slices, num_variables" + -// ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; -// ps = conn.prepareStatement(vcmExpHiSQL); -// -// HumanReadableExportData meta = exportSpecs.getHumanReadableExportData(); -// TimeSpecs ts = exportSpecs.getTimeSpecs(); -// String[] vars = exportSpecs.getVariableSpecs().getVariableNames(); -// -// String timeRange = ts.toString(); -// String[] time_parts = timeRange.split("/"); -// BigDecimal startTime = new BigDecimal(time_parts[0]); -// BigDecimal endTime = new BigDecimal(time_parts[1]); -// -// -// ps.setLong (2, jobID); -// ps.setLong (3, userRef); -// ps.setLong (4, modelRef); -// ps.setString (5, exportFormat); -// ps.setTimestamp (6, exportDate); -// ps.setString (7, uri); -// ps.setString (8, exportSpecs.getVCDataIdentifier().getID()); -// ps.setString (9, meta.simulationName); -// ps.setString (10, meta.applicationName); -// ps.setString (11, meta.biomodelName); -// ps.setArray (12, conn.createArrayOf("text", vars)); -// ps.setBigDecimal (13, startTime); -// ps.setBigDecimal (14, endTime); -// ps.setString (15, meta.serverSavedFileName); -// ps.setString (16, meta.applicationType); -// ps.setBoolean (17, meta.nonSpatial); -// ps.setInt (18, meta.zSlices); -// ps.setInt (19, meta.tSlices); -// ps.setInt (20, meta.numChannels); -// ps.executeUpdate(); -// -// -// String vcmExpHisPVSQL = // SQL statement for inserting into vc_model_parameter_value table in VCell server -// "INSERT INTO vc_model_parameter_values (" + -// "export_id, user_ref, model_ref, parameter_name," + -// "parameter_original, parameter_changed" + -// ") VALUES (?,?,?,?,?,?)"; -// psParam = conn.prepareStatement(vcmExpHisPVSQL); -// -// -// for (String entry : meta.differentParameterValues) { -// String[] parts = entry.split(":"); -// if (parts.length == 3) { -// //psParam.setLong (1, historyId); -// psParam.setLong (2, userRef); -// psParam.setLong (3, modelRef); -// psParam.setString (4, parts[0]); -// psParam.setBigDecimal (5, new BigDecimal(parts[1])); -// psParam.setBigDecimal (6, new BigDecimal(parts[2])); -// psParam.addBatch(); -// } -// } -// psParam.executeBatch(); -// } -// catch(SQLException e){ -// lg.error("Error exporting to database",e); -// } -// finally { -// try{ if(rsSeq !=null) rsSeq.close(); }catch(Exception ign){} -// try{ if(psParam !=null) psParam.close(); }catch(Exception ign){} -// try{ if(ps !=null) ps.close(); }catch(Exception ign){} -// try{ if(conn !=null) conn.close(); }catch(Exception ign){} -// } -//} -// -// -//} diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index 47f6c1d096..c34fa82f93 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -88,17 +88,17 @@ public void createClients() throws ApiException, DataAccessException, PropertyVe VCDataIdentifier vcdId = new VCSimulationDataIdentifier(vcSimId, 0); - GeometrySpecs geometrySpecs = new GeometrySpecs(null, 1, 1, 1); + GeometrySpecs geometrySpecs = new GeometrySpecs(null, 1, 1, ExportEnums.GeometryMode.GEOMETRY_FULL); double[] times = new double[]{0.0, 1.0}; - TimeSpecs timeSpecs = new TimeSpecs(0, 1, times, times.length); + TimeSpecs timeSpecs = new TimeSpecs(0, 1, times, ExportEnums.TimeMode.TIME_RANGE); - VariableSpecs variableSpecs = new VariableSpecs(new String[]{"X"}, 1); + VariableSpecs variableSpecs = new VariableSpecs(new String[]{"X"}, ExportEnums.VariableMode.VARIABLE_ONE); - FormatSpecificSpecs formatSpecific = new FormatSpecificSpecs() { + FormatSpecificSpecs formatSpecific = new FormatSpecificSpecs("N5") { @Override public boolean equals(Object o) { return this==o; } @Override public String toString() { return "DUMMY"; } }; diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index 9725b52569..55f1b0c954 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -54,6 +54,7 @@ public class DBTopLevel extends AbstractDBTopLevel{ private final BioModelDbDriver bioModelDB; private final MathModelDbDriver mathModelDB; private final UserDbDriver userDB; + private final ExportHistoryDBDriver exportHistoryDBDriver; // private DBCacheTable dbCacheTable = null; private static final int SQL_ERROR_CODE_BADCONNECTION = 1010; //?????????????????????????????????????? @@ -76,6 +77,7 @@ public class DBTopLevel extends AbstractDBTopLevel{ this.userDB = new UserDbDriver(); this.bioModelDB = new BioModelDbDriver(databaseSyntax,keyFactory); this.mathModelDB = new MathModelDbDriver(databaseSyntax, keyFactory); + this.exportHistoryDBDriver = new ExportHistoryDBDriver(databaseSyntax, keyFactory); } @@ -2260,7 +2262,7 @@ public void insertExportHistory(User user, ExportHistoryDBDriver.ExportHistory e Object lock = new Object(); Connection con = conFactory.getConnection(lock); try { - exportHistoryDB.addExportHistory(con, user, exportHistoryValues, conFactory.getKeyFactory()); + exportHistoryDBDriver.addExportHistory(con, user, exportHistoryValues, conFactory.getKeyFactory()); } catch (Throwable e) { lg.error(e.getMessage(),e); try { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 65c057d23f..3abbf29570 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -145,68 +145,4 @@ public ResultSet getExportHistoryForUser(Connection conn, User user) throws SQLE return ps.executeQuery(); } - - public static void main(String[] args) throws SQLException, PermissionException, DataAccessException { - try (Connection connection = DriverManager.getConnection( - "jdbc:postgresql://localhost:5432/postgres", "quarkus", "quarkus")) { - - ExportHistoryDBDriver dbDriver = new ExportHistoryDBDriver(null, null); - - - GeometrySpecs testGeometrySpecs = new GeometrySpecs(null, 100, 100, 1); - TimeSpecs testTimeSpecs = new TimeSpecs(0, 1, new double[]{1, 1}, 1); - String[] testVarNames = new String[]{"A", "B"}; - VariableSpecs testVariableSpecs = new VariableSpecs(testVarNames, 1); - KeyValue simKey = new KeyValue("12345"); - User user = new User("Administrator", new KeyValue("2")); - VCSimulationIdentifier vcSimID = new VCSimulationIdentifier(simKey, user); - VCDataIdentifier vcdID = new VCSimulationDataIdentifier(vcSimID, 456); - FormatSpecificSpecs testFormatSpecificSpecs = new FormatSpecificSpecs() { - @Override public boolean equals(Object obj) { return this == obj; } - @Override public String toString() { return "DummyFormatSpecificSpecs"; } - }; - HumanReadableExportData meta = new HumanReadableExportData( - "MySimulation","MyApp","MyBioModel", - new ArrayList<>(), "result.n5","N5", false, new HashMap<>() - ); - Timestamp testExportDate = new Timestamp(System.currentTimeMillis()); - ExportSpecs exportSpecs = new ExportSpecs( - vcdID, ExportFormat.N5, testVariableSpecs, testTimeSpecs, - testGeometrySpecs, testFormatSpecificSpecs, "testsim","testname" - ); - exportSpecs.setExportMetaData(meta); - - -// ExportHistoryDBDriver.ExportHistory history = new ExportHistoryDBDriver.ExportHistory( -// /*jobID=*/ 1, -// /*modelRef=*/ 2, -// /*format=*/ ExportFormat.N5, -// /*date=*/ testExportDate, -// /*uri=*/ "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", -// /*specs=*/ exportSpecs -// ); - - - //dbDriver.addExportHistory(connection, user, history); - - System.out.println("=== Test get before deletion ==="); - try (ResultSet rs = dbDriver.getExportHistoryForUser(connection, user)) { - while (rs.next()) { - System.out.println( - "id=" + rs.getLong("id") - + ", data_id=" + rs.getString("data_id") - + ", export_format=" + rs.getString("export_format") - ); - } - } - - - dbDriver.deleteExportHistory(connection, exportSpecs); - - } catch (SQLException e) { - System.err.println("SQLException: " + e.getMessage()); - } - } - - } From a32030d48d52537e893dfff2f3b9c1dfebf35be0 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 17 Mar 2026 08:15:59 -0400 Subject: [PATCH 31/65] Fix Problematic Artifacts from Rebase --- vcell-core/pom.xml | 12 -- .../export/server/ExportServiceImpl.java | 94 ++-------- .../services/Exports/ExportStatusCreator.java | 163 ------------------ .../vcell/modeldb/DatabaseServerImpl.java | 13 +- 4 files changed, 21 insertions(+), 261 deletions(-) delete mode 100644 vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportStatusCreator.java diff --git a/vcell-core/pom.xml b/vcell-core/pom.xml index 9c335d19e2..204d48a916 100644 --- a/vcell-core/pom.xml +++ b/vcell-core/pom.xml @@ -692,18 +692,6 @@ microprofile-openapi-api ${microprofile-openapi.version} - - org.vcell - vcell-server - 0.0.1-SNAPSHOT - compile - - - org.vcell - vcell-rest - 1.0.0-SNAPSHOT - compile - diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java index 9abae6e5ef..51d5a91f14 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportServiceImpl.java @@ -9,40 +9,29 @@ */ package cbit.vcell.export.server; -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collection; -import java.util.zip.DataFormatException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; +import cbit.rmi.event.ExportEvent; import cbit.rmi.event.ExportEventController; +import cbit.vcell.export.nrrd.NrrdInfo; +import cbit.vcell.resource.PropertyLoader; +import cbit.vcell.simdata.DataServerImpl; +import cbit.vcell.simdata.OutputContext; +import cbit.vcell.solver.VCSimulationDataIdentifier; +import com.google.common.io.Files; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.vcell.db.ConnectionFactory; -import org.vcell.db.DatabaseSyntax; -import org.vcell.db.KeyFactory; import org.vcell.util.ClientTaskStatusSupport; import org.vcell.util.DataAccessException; import org.vcell.util.UserCancelException; import org.vcell.util.document.User; -import com.google.common.io.Files; - -import cbit.rmi.event.ExportEvent; -import cbit.vcell.export.nrrd.NrrdInfo; -import cbit.vcell.resource.PropertyLoader; -import cbit.vcell.simdata.DataServerImpl; -import cbit.vcell.simdata.OutputContext; -import cbit.vcell.solver.VCSimulationDataIdentifier; -import cbit.vcell.modeldb.ExportHistoryDBDriver; -import org.vcell.restq.db.AgroalConnectionFactory; +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.zip.DataFormatException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; @@ -59,10 +48,6 @@ public ExportEventController getEventController() { } - - @Inject - AgroalConnectionFactory agroalConnectionFactory; - public ExportServiceImpl() { } @@ -71,57 +56,6 @@ public ExportEvent makeRemoteFile(OutputContext outputContext,User user, DataSer return makeRemoteFile(outputContext,user, dataServerImpl, exportSpecs, eventController, JobRequest.createExportJobRequest(user).getExportJobID()); } - - -/** - * Insert the method's description here. - * Creation date: (4/1/2001 11:20:45 AM) - * @deprecated - */ -protected ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, String format, String location,ExportSpecs exportSpecs) throws SQLException, DataAccessException { - User user = null; - Object object = jobRequestIDs.get(new Long(jobID)); - if (object != null) { - user = (User)object; - } - TimeSpecs timeSpecs = (exportSpecs!=null)?exportSpecs.getTimeSpecs():(null); - VariableSpecs varSpecs = (exportSpecs!=null)?exportSpecs.getVariableSpecs():(null); - final KeyValue dataKey; - if (vcdID instanceof VCSimulationDataIdentifier) { - dataKey = ((VCSimulationDataIdentifier)vcdID).getSimulationKey(); - }else if (vcdID instanceof ExternalDataIdentifier) { - dataKey = ((ExternalDataIdentifier)vcdID).getSimulationKey(); - }else { - throw new RuntimeException("unexpected VCDataIdentifier"); - } - ExportEvent event = new ExportEvent( - this, jobID, user, vcdID.getID(), dataKey, ExportEvent.EXPORT_COMPLETE, - format, location, null, timeSpecs, varSpecs); - event.setHumanReadableExportData(exportSpecs != null ? exportSpecs.getHumanReadableExportData() : null); - - assert exportSpecs != null; - event.setHumanReadableExportData(exportSpecs.getHumanReadableExportData()); - assert user != null; - - - - try (Connection conn = agroalConnectionFactory.getConnection(null)) { - exportHistoryDBDriver.addExportHistory(conn, vcdID.getOwner(), new ExportHistoryDBDriver.ExportHistory(jobID, 1, exportSpecs.getFormat(), new Timestamp(System.currentTimeMillis()), location, exportSpecs), agroalConnectionFactory.getKeyFactory()); - - } - - -//exportToDB( -// jobID, -// Long.parseLong(user.getID().toString()), -// Long.parseLong(vcdID.getOwner().getID().toString()), -// format, -// new Timestamp(System.currentTimeMillis()), -// location, -// exportSpecs -// ); - fireExportEvent(event); - return event; public ExportEvent makeRemoteFile(OutputContext outputContext, User user, DataServerImpl dataServer, ExportSpecs exportSpecs, boolean zip, ClientTaskStatusSupport clientTaskStatusSupport)throws DataAccessException { return makeRemoteFile(outputContext, user, dataServer, exportSpecs, eventController, zip, clientTaskStatusSupport, JobRequest.createExportJobRequest(user).getExportJobID()); } diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportStatusCreator.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportStatusCreator.java deleted file mode 100644 index df1711ff71..0000000000 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportStatusCreator.java +++ /dev/null @@ -1,163 +0,0 @@ -package org.vcell.restq.services.Exports; - -import cbit.rmi.event.ExportEvent; -import cbit.rmi.event.ExportListener; -import cbit.rmi.event.ExportStatusEventCreator; -import cbit.vcell.export.server.ExportSpecs; -import cbit.vcell.export.server.ExportSpecss; -import cbit.vcell.export.server.TimeSpecs; -import cbit.vcell.export.server.VariableSpecs; -import cbit.vcell.solver.VCSimulationDataIdentifier; -import io.smallrye.mutiny.Multi; -import io.smallrye.mutiny.helpers.MultiEmitterProcessor; -import jakarta.enterprise.context.ApplicationScoped; -import org.vcell.util.ObjectNotFoundException; -import org.vcell.util.document.ExternalDataIdentifier; -import org.vcell.util.document.KeyValue; -import org.vcell.util.document.User; -import org.vcell.util.document.VCDataIdentifier; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -@ApplicationScoped -public class ExportStatusCreator implements ExportStatusEventCreator { - private final ConcurrentHashMap jobRequestToUser = new ConcurrentHashMap<>(); - private final ConcurrentHashMap> listeners = new ConcurrentHashMap<>(); - private final ConcurrentHashMap> mostRecentExportEvents = new ConcurrentHashMap<>(); // TODO: Clean out this set - - - protected ExportSpecs exportExists(ExportSpecs exportSpecs) { - // Call DB for export history and check if it exists. Store in cache if it exists for future requests. - return exportSpecs; - } - - public ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, String format, String location, ExportSpecs exportSpecs) { - User user = jobRequestToUser.get(jobID); - String key = entryKey(user, jobID); - - TimeSpecs timeSpecs = (exportSpecs!=null)?exportSpecs.getTimeSpecs():(null); - VariableSpecs varSpecs = (exportSpecs!=null)?exportSpecs.getVariableSpecs():(null); - final KeyValue dataKey; - if (vcdID instanceof VCSimulationDataIdentifier) { - dataKey = ((VCSimulationDataIdentifier)vcdID).getSimulationKey(); - }else if (vcdID instanceof ExternalDataIdentifier) { - dataKey = ((ExternalDataIdentifier)vcdID).getSimulationKey(); - }else { - throw new RuntimeException("unexpected VCDataIdentifier"); - } - ExportEvent event = new ExportEvent( - this, jobID, user, vcdID.getID(), dataKey, ExportSpecss.ExportProgressType.EXPORT_COMPLETE, - format, location, null, timeSpecs, varSpecs); - event.setHumanReadableExportData(exportSpecs != null ? exportSpecs.getHumanReadableExportData() : null); - event.setHumanReadableExportData(exportSpecs.getHumanReadableExportData()); - - - synchronized (this){ - if (!listeners.containsKey(key)) { - throw new RuntimeException("Did not find entry for user " + user.getName() + " and job id " + jobID); - } - listeners.get(key).onNext(event); - listeners.get(key).complete(); - replaceSetEntry(user, event); - removeServerExportListener(user, jobID); - jobRequestToUser.remove(jobID); - } - - return event; - } - - public synchronized void addExportListener(ExportListener listener) { - throw new IllegalCallerException("addExportListener not implemented for the server"); - } - - public synchronized Multi getUsersExportStatus(User user, long exportJobID) throws ObjectNotFoundException { - String key = entryKey(user, exportJobID); - if (!listeners.containsKey(key)) { - throw new ObjectNotFoundException("Did not find entry for user " + user.getName() + " and job id " + exportJobID); - } - return listeners.get(key).toMulti(); - } - - public synchronized Set getMostRecentExportStatus (User user) throws ObjectNotFoundException { - if (!mostRecentExportEvents.containsKey(user)) { - throw new ObjectNotFoundException("Did not find entry for user " + user.getName()); - } - return mostRecentExportEvents.get(user); - } - - public synchronized void addServerExportListener(User user, long exportJobID){ - MultiEmitterProcessor emitter = MultiEmitterProcessor.create(); - String key = entryKey(user, exportJobID); - listeners.put(key, emitter); - jobRequestToUser.put(exportJobID, user); - ExportEvent event = new ExportEvent( - this, exportJobID, user, "", null, ExportSpecss.ExportProgressType.EXPORT_ASSEMBLING, - "", "", 0.0, null, null); - if (!mostRecentExportEvents.containsKey(user)) { - mostRecentExportEvents.put(user, new HashSet<>()); - } - mostRecentExportEvents.get(user).add(event); - } - - public void fireExportAssembling(long jobID, VCDataIdentifier vcdID, String format) { - User user = jobRequestToUser.get(jobID); - ExportEvent event = new ExportEvent(this, jobID, user, vcdID, ExportSpecss.ExportProgressType.EXPORT_ASSEMBLING, format, null, null, null, null); - fireExportEvent(event); - } - - public synchronized void fireExportEvent(ExportEvent event) { - String key = entryKey(event.getUser(), event.getJobID()); - if (!listeners.containsKey(key)){ - throw new RuntimeException("Did not find entry for user " + event.getUser().getName() + " and job id " + event.getJobID()); - } - MultiEmitterProcessor listener = listeners.get(event.getUser().getName() + event.getJobID()); - listener.onNext(event); - replaceSetEntry(event.getUser(), event); - } - - public synchronized void fireExportFailed(long jobID, VCDataIdentifier vcdID, String format, String message) { - User user = jobRequestToUser.get(jobID); - String key = entryKey(user, jobID); - if (!listeners.containsKey(key)) { - throw new RuntimeException("Did not find entry for user " + user.getName() + " and job id " + jobID); - } - ExportEvent event = new ExportEvent(this, jobID, user, vcdID, ExportSpecss.ExportProgressType.EXPORT_FAILURE, format, message, null, null, null); - listeners.get(key).onNext(event); - listeners.get(key).complete(); - - replaceSetEntry(user, event); - removeServerExportListener(user, jobID); - jobRequestToUser.remove(jobID); - } - - public void fireExportProgress(long jobID, VCDataIdentifier vcdID, String format, double progress) { - User user = jobRequestToUser.get(jobID); - - ExportEvent event = new ExportEvent(this, jobID, user, vcdID, ExportSpecss.ExportProgressType.EXPORT_PROGRESS, format, null, progress, null, null); - fireExportEvent(event); - } - - public void fireExportStarted(long jobID, VCDataIdentifier vcdID, String format) { - User user = jobRequestToUser.get(jobID); - - ExportEvent event = new ExportEvent(this, jobID, user, vcdID, ExportSpecss.ExportProgressType.EXPORT_START, format, null, null, null, null); - fireExportEvent(event); - } - - public void removeServerExportListener(User user, long exportJobID){ - listeners.remove(user.getName() + exportJobID); - } - - private String entryKey(User user, long jobID){ - return user.getName() + jobID; - } - - private void replaceSetEntry(User user, ExportEvent newEvent){ - mostRecentExportEvents.get(user).remove(newEvent); - mostRecentExportEvents.get(user).add(newEvent); - } -} diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java index 1a1d456d4f..537c6fa78f 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java @@ -1355,10 +1355,11 @@ public BigString saveVCImageAs(User user, BigString vcImageXML, java.lang.String } } -public void addExportHistory(User user, ExportHistoryDBDriver.ExportHistory exportHistory) throws DataAccessException { - try { - dbTop.insertExportHistory(user, exportHistory, true); - } catch (SQLException e) { - throw new DataAccessException(e); - } + public void addExportHistory(User user, ExportHistoryDBDriver.ExportHistory exportHistory) throws DataAccessException { + try { + dbTop.insertExportHistory(user, exportHistory, true); + } catch (SQLException e) { + throw new DataAccessException(e); + } + } } From 1178ba1687e4ee43bd3611354b241c936518e201 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 17 Mar 2026 10:52:02 -0400 Subject: [PATCH 32/65] Relocate Export History Rep for DB --- .../vcell/restq/services/ExportService.java | 7 ++-- .../org/vcell/restq/ExportHistoryTest.java | 15 +++----- .../java/cbit/vcell/modeldb/DBTopLevel.java | 3 +- .../vcell/modeldb/DatabaseServerImpl.java | 2 +- .../vcell/modeldb/ExportHistoryDBDriver.java | 34 +++++-------------- .../cbit/vcell/modeldb/ExportHistoryRep.java | 16 +++++++++ 6 files changed, 35 insertions(+), 42 deletions(-) create mode 100644 vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java b/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java index 6673a4cac7..e01f3eecce 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java @@ -1,11 +1,10 @@ package org.vcell.restq.services; import cbit.vcell.modeldb.DatabaseServerImpl; -import cbit.vcell.modeldb.ExportHistoryDBDriver; +import cbit.vcell.modeldb.ExportHistoryRep; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import org.vcell.restq.db.AgroalConnectionFactory; -import org.vcell.restq.handlers.ExportResource; import org.vcell.util.DataAccessException; import org.vcell.util.document.User; @@ -19,12 +18,12 @@ public ExportService(AgroalConnectionFactory connectionFactory) throws DataAcces } - public ExportHistoryDBDriver.ExportHistory getExportHistory(User user) throws DataAccessException { + public ExportHistoryRep getExportHistory(User user) throws DataAccessException { // TODO: Pipe down to DB layer return null; } - public void addExportHistory(User user, ExportHistoryDBDriver.ExportHistory history) throws DataAccessException { + public void addExportHistory(User user, ExportHistoryRep history) throws DataAccessException { databaseServer.addExportHistory(user, history); } diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index c34fa82f93..2e3fdbd715 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -2,11 +2,10 @@ import cbit.vcell.biomodel.BioModel; import cbit.vcell.export.server.*; -import cbit.vcell.mapping.MappingException; import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.modeldb.ExportHistoryDBDriver; +import cbit.vcell.modeldb.ExportHistoryRep; import cbit.vcell.resource.PropertyLoader; -import cbit.vcell.simdata.SpatialSelection; import cbit.vcell.solver.VCSimulationDataIdentifier; import cbit.vcell.solver.VCSimulationIdentifier; import cbit.vcell.xml.XMLSource; @@ -20,7 +19,6 @@ import org.vcell.restclient.ApiException; import org.vcell.restq.config.CDIVCellConfigProvider; import org.vcell.restq.db.AgroalConnectionFactory; -import org.vcell.restq.handlers.ExportResource; import org.vcell.util.BigString; import org.vcell.util.DataAccessException; import org.vcell.util.DependencyException; @@ -39,14 +37,11 @@ import java.sql.Timestamp; import java.time.Instant; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; -import java.util.List; import static org.bouncycastle.math.raw.Nat.equalTo; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertEquals; -import static org.vcell.sybil.util.http.pathwaycommons.PCRParameter.Output.xml; import static org.vcell.util.VCAssert.assertFalse; import static org.vcell.util.VCAssert.assertTrue; @@ -148,7 +143,7 @@ public void testAddExportHistory() { driver.addExportHistory( conn, user, - new ExportHistoryDBDriver.ExportHistory( + new ExportHistoryRep( 42L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, @@ -189,7 +184,7 @@ public void testDeleteExportHistory() throws SQLException { driver.addExportHistory(conn, user, - new ExportHistoryDBDriver.ExportHistory(7L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "to-delete", exportSpecs), + new ExportHistoryRep(7L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "to-delete", exportSpecs), agroalConnectionFactory.getKeyFactory() ); @@ -232,11 +227,11 @@ public void testGetExportHistory() throws SQLException, DataAccessException { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); driver.addExportHistory(conn, user, - new ExportHistoryDBDriver.ExportHistory(100L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri100", exportSpecs), + new ExportHistoryRep(100L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri100", exportSpecs), agroalConnectionFactory.getKeyFactory() ); driver.addExportHistory(conn, user, - new ExportHistoryDBDriver.ExportHistory(101L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri101", exportSpecs), + new ExportHistoryRep(101L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri101", exportSpecs), agroalConnectionFactory.getKeyFactory() ); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index 55f1b0c954..eebd0b0878 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -15,7 +15,6 @@ import cbit.sql.QueryHashtable; import cbit.sql.RecordChangedException; import cbit.vcell.biomodel.BioModelMetaData; -import cbit.vcell.export.server.ExportSpecs; import cbit.vcell.field.FieldDataAllDBEntries; import cbit.vcell.field.FieldDataExternalDataIDEntry; import cbit.vcell.field.io.CopyFieldDataResult; @@ -2258,7 +2257,7 @@ public SimulationRep getSimulationRep(KeyValue simKey, boolean bEnableRetry) thr } } - public void insertExportHistory(User user, ExportHistoryDBDriver.ExportHistory exportHistoryValues, boolean bEnableRetry) throws SQLException, DataAccessException { + public void insertExportHistory(User user, ExportHistoryRep exportHistoryValues, boolean bEnableRetry) throws SQLException, DataAccessException { Object lock = new Object(); Connection con = conFactory.getConnection(lock); try { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java index 537c6fa78f..874b49150c 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java @@ -1355,7 +1355,7 @@ public BigString saveVCImageAs(User user, BigString vcImageXML, java.lang.String } } - public void addExportHistory(User user, ExportHistoryDBDriver.ExportHistory exportHistory) throws DataAccessException { + public void addExportHistory(User user, ExportHistoryRep exportHistory) throws DataAccessException { try { dbTop.insertExportHistory(user, exportHistory, true); } catch (SQLException e) { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 3abbf29570..9c9006282e 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -1,8 +1,6 @@ package cbit.vcell.modeldb; import cbit.vcell.export.server.*; -import cbit.vcell.solver.VCSimulationDataIdentifier; -import cbit.vcell.solver.VCSimulationIdentifier; import org.vcell.db.DatabaseSyntax; import org.vcell.db.KeyFactory; import org.vcell.util.DataAccessException; @@ -11,14 +9,9 @@ import org.vcell.util.PermissionException; import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; -import org.vcell.util.document.VCDataIdentifier; -import org.vcell.util.document.VersionableType; import java.math.BigDecimal; import java.sql.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.StringJoiner; public class ExportHistoryDBDriver { public static final ExportHistoryTable exportHistoryTable = ExportHistoryTable.table; @@ -39,19 +32,10 @@ public ExportHistoryDBDriver(DatabaseSyntax databaseSyntax, KeyFactory keyFactor } - public record ExportHistory( - long jobID, - long modelRef, - ExportFormat exportFormat, - Timestamp exportDate, - String uri, - ExportSpecs exportSpecs - ){} - - public void addExportHistory(Connection conn, User user, ExportHistory exportHistory, KeyFactory keyFactory) + public void addExportHistory(Connection conn, User user, ExportHistoryRep exportHistory, KeyFactory keyFactory) throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { - ExportSpecs specs = exportHistory.exportSpecs; + ExportSpecs specs = exportHistory.exportSpecs(); HumanReadableExportData meta = specs.getHumanReadableExportData(); TimeSpecs ts = specs.getTimeSpecs(); String[] vars = specs.getVariableSpecs().getVariableNames(); @@ -64,12 +48,12 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis try (PreparedStatement ps = conn.prepareStatement(ehSQL)) { ExportHistoryTable.table.bindForInsert(ps, keyValue, - exportHistory.jobID, + exportHistory.jobID(), Long.parseLong(user.getID().toString()), - exportHistory.modelRef, - exportHistory.exportFormat, - exportHistory.exportDate, - exportHistory.uri, + exportHistory.modelRef(), + exportHistory.exportFormat(), + exportHistory.exportDate(), + exportHistory.uri(), specs.getVCDataIdentifier().getID(), meta.simulationName, meta.applicationName, @@ -98,9 +82,9 @@ public void addExportHistory(Connection conn, User user, ExportHistory exportHis if (parts.length == 3) { ModelParameterValuesTable.table.bindForInsert(ps2, - exportHistory.jobID, + exportHistory.jobID(), Long.parseLong(user.getID().toString()), - exportHistory.modelRef, + exportHistory.modelRef(), parts[0], new BigDecimal(parts[1]), new BigDecimal(parts[2]) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java new file mode 100644 index 0000000000..9484717947 --- /dev/null +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java @@ -0,0 +1,16 @@ +package cbit.vcell.modeldb; + +import cbit.vcell.export.server.ExportFormat; +import cbit.vcell.export.server.ExportSpecs; + +import java.sql.Timestamp; + +public record ExportHistoryRep( + long jobID, + long modelRef, + ExportFormat exportFormat, + Timestamp exportDate, + String uri, + ExportSpecs exportSpecs +) { +} From 34b8cdb33113e879aebd6170f6495a73fdc94f9e Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Wed, 18 Mar 2026 11:46:18 -0400 Subject: [PATCH 33/65] Replace Different Param String with Record Instead of a custom string which needs to be parsed, use a record. --- .../events/ExportHumanReadableDataSpec.java | 7 ++++-- .../client/data/ExportDataRepresentation.java | 7 ++++-- .../client/data/ExportedDataTableModel.java | 5 ++-- .../vcell/client/data/ExportedDataViewer.java | 9 ++++--- .../vcell/client/data/PDEExportDataPanel.java | 8 ++++-- .../server/HumanReadableExportData.java | 11 ++++++-- .../org/vcell/restq/ExportHistoryTest.java | 2 +- .../vcell/modeldb/ExportHistoryDBDriver.java | 25 ++++++++----------- 8 files changed, 45 insertions(+), 29 deletions(-) diff --git a/vcell-api-types/src/main/java/org/vcell/api/types/events/ExportHumanReadableDataSpec.java b/vcell-api-types/src/main/java/org/vcell/api/types/events/ExportHumanReadableDataSpec.java index 4fbea677d1..fff26d5511 100644 --- a/vcell-api-types/src/main/java/org/vcell/api/types/events/ExportHumanReadableDataSpec.java +++ b/vcell-api-types/src/main/java/org/vcell/api/types/events/ExportHumanReadableDataSpec.java @@ -1,14 +1,17 @@ package org.vcell.api.types.events; +import cbit.vcell.export.server.HumanReadableExportData; + import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; public class ExportHumanReadableDataSpec { public final String bioModelName; public String applicationName; public String simulationName; - public ArrayList differentParameterValues; + public List differentParameterValues; public String serverSavedFileName; public String applicationType; public boolean nonSpatial; @@ -18,7 +21,7 @@ public class ExportHumanReadableDataSpec { public int numChannels; public ExportHumanReadableDataSpec(String bioModelName, String applicationName, String simulationName, - ArrayList differentParameterValues, + List differentParameterValues, String serverSavedFileName, String applicationType, boolean nonSpatial, Map subVolume, int zSlices, int tSlices, int numChannels){ this.bioModelName = bioModelName; diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/ExportDataRepresentation.java b/vcell-client/src/main/java/cbit/vcell/client/data/ExportDataRepresentation.java index 4035a665c2..6916075bee 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/ExportDataRepresentation.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/ExportDataRepresentation.java @@ -1,7 +1,10 @@ package cbit.vcell.client.data; +import cbit.vcell.export.server.HumanReadableExportData; + import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Stack; public class ExportDataRepresentation { @@ -34,7 +37,7 @@ public static class SimulationExportDataRepresentation { public String variables; public String startAndEndTime; - public ArrayList differentParameterValues; + public List differentParameterValues; public String savedFileName; public String applicationType; public boolean nonSpatial; @@ -44,7 +47,7 @@ public static class SimulationExportDataRepresentation { public SimulationExportDataRepresentation(String exportDate, String uri, String jobID, String dataID, String simulationName, String applicationName, String biomodelName, String variables, String startAndEndTime, - ArrayList differentParameterValues, + List differentParameterValues, String savedFileName, String applicationType, boolean nonSpatial, int zSlices, int tSlices, int numVariables){ this.exportDate = exportDate; diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/ExportedDataTableModel.java b/vcell-client/src/main/java/cbit/vcell/client/data/ExportedDataTableModel.java index 22a450d0e1..14d4766222 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/ExportedDataTableModel.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/ExportedDataTableModel.java @@ -1,6 +1,7 @@ package cbit.vcell.client.data; import cbit.vcell.client.desktop.biomodel.VCellSortTableModel; +import cbit.vcell.export.server.HumanReadableExportData; import cbit.vcell.model.ModelProcess; import org.vcell.util.gui.ScrollTable; @@ -184,13 +185,13 @@ public static class TableData { public String appName = null; public String simName = null; public String variables = null; - public ArrayList differentParameterValues; + public List differentParameterValues; public boolean nonSpatial; public String applicationType = null; public TableData(String jobID, String simID, String dateExported, String format, String link, String name, String bioModelName, String timeSlice, String appName, String simName, String variables, - ArrayList differentParameterValues, boolean nonSpatial, String applicationType){ + List differentParameterValues, boolean nonSpatial, String applicationType){ this.jobID = jobID; this.simID = simID; this.dateExported = dateExported; diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/ExportedDataViewer.java b/vcell-client/src/main/java/cbit/vcell/client/data/ExportedDataViewer.java index b51bdacb85..41c1533dd5 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/ExportedDataViewer.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/ExportedDataViewer.java @@ -3,6 +3,7 @@ import cbit.vcell.client.ClientRequestManager; import cbit.vcell.client.desktop.biomodel.DocumentEditorSubPanel; import cbit.vcell.export.server.ExportFormat; +import cbit.vcell.export.server.HumanReadableExportData; import cbit.vcell.graph.GraphConstants; import cbit.vcell.mapping.SimulationContext; import cbit.vcell.resource.ResourceUtil; @@ -33,6 +34,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.List; public class ExportedDataViewer extends DocumentEditorSubPanel implements ActionListener, PropertyChangeListener, ListSelectionListener, KeyListener { @@ -509,7 +511,7 @@ public void valueChanged(ListSelectionEvent e) { exportVariableText.setText(""); return; } - ArrayList differentParameterValues = rowData.differentParameterValues; + List differentParameterValues = rowData.differentParameterValues; StyleContext styleContext = new StyleContext(); // AttributeSet attributeSet = styleContext.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.) StyledDocument doc = new DefaultStyledDocument(); @@ -528,10 +530,9 @@ public void valueChanged(ListSelectionEvent e) { } parameterScrollTableModel.resetData(); - for(int i =0; i < differentParameterValues.size(); i++){ - String[] parameterTokens = differentParameterValues.get(i).split(":"); + for (HumanReadableExportData.DifferentParameterValues differentParameterValue : differentParameterValues) { ParameterTableModelExport.ParameterTableData data = new ParameterTableModelExport.ParameterTableData( - parameterTokens[0], parameterTokens[1], parameterTokens[2] + differentParameterValue.parameterName(), differentParameterValue.originalValue(), differentParameterValue.changedValue() ); parameterScrollTableModel.addRow(data); } diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java index 5b2a2dd4c3..e0c7f87e80 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java @@ -48,6 +48,8 @@ import java.net.URL; import java.nio.channels.FileChannel; import java.util.*; +import java.util.List; + /** * This type was created in VisualAge. */ @@ -650,7 +652,7 @@ private ExportSpecs getExportSpecs() { MathOverrides mathOverrides = getSimulation().getMathOverrides(); String[] filteredConstants = mathOverrides.getFilteredConstantNames(); - ArrayList differentParameterValues = new ArrayList<>(); + List differentParameterValues = new ArrayList<>(); VCDataIdentifier vcDataIdentifier = getPdeDataContext().getVCDataIdentifier(); if (vcDataIdentifier instanceof VCSimulationDataIdentifier){ for (String filteredConstant : filteredConstants) { @@ -659,7 +661,9 @@ private ExportSpecs getExportSpecs() { MathOverrides.ScanIndex scanIndex = simulation.getScanIndex(jobIndex); String setValue = mathOverrides.getActualExpression(filteredConstant, scanIndex).infix(); if(!defaultValue.equals(setValue)){ - differentParameterValues.add(filteredConstant + ":" +defaultValue + ":" + setValue); + differentParameterValues.add(new HumanReadableExportData.DifferentParameterValues( + filteredConstant, defaultValue, setValue + )); } } } diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/HumanReadableExportData.java b/vcell-core/src/main/java/cbit/vcell/export/server/HumanReadableExportData.java index 918b3518b6..07a9897c0b 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/HumanReadableExportData.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/HumanReadableExportData.java @@ -6,13 +6,20 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; public class HumanReadableExportData implements Serializable { + public record DifferentParameterValues( + String parameterName, + String originalValue, + String changedValue + ){} + public final String simulationName; public final String biomodelName; public final String applicationName; - public ArrayList differentParameterValues; + public List differentParameterValues; public String applicationType; // File name that is saved by the user or server. In N5 case it'll be the dataset name. This way individual datasets can be automatically opened public String serverSavedFileName; @@ -24,7 +31,7 @@ public class HumanReadableExportData implements Serializable { @JsonCreator public HumanReadableExportData(@JsonProperty("simulationName") String simulationName, @JsonProperty("applicationName") String applicationName, - @JsonProperty("biomodelName") String biomodelName, @JsonProperty("differentParameterValues") ArrayList differentParameterValues, + @JsonProperty("biomodelName") String biomodelName, @JsonProperty("differentParameterValues") List differentParameterValues, @JsonProperty("serverSavedFileName") String serverSavedFileName, @JsonProperty("applicationType") String applicationType, @JsonProperty("nonSpatial") boolean nonSpatial, @JsonProperty("subVolume") Map subVolume){ this.simulationName = simulationName; diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index 2e3fdbd715..4be8555a34 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -103,7 +103,7 @@ public void createClients() throws ApiException, DataAccessException, PropertyVe "simName", // simulation name "appName", // application name savedBioModel.getName(), // biomodel name - new ArrayList(), // no parameter changes + new ArrayList(), // no parameter changes vcdId.getID(), // dataId "out.n5", // serverSavedFileName false, // nonSpatial? diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 9c9006282e..0c05e9525a 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -77,20 +77,17 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export // 2) insert each parameter change String pvSQL = ModelParameterValuesTable.table.getInsertSQL(); try (PreparedStatement ps2 = conn.prepareStatement(pvSQL)) { - for (String entry : meta.differentParameterValues) { - String[] parts = entry.split(":"); - if (parts.length == 3) { - ModelParameterValuesTable.table.bindForInsert(ps2, - - exportHistory.jobID(), - Long.parseLong(user.getID().toString()), - exportHistory.modelRef(), - parts[0], - new BigDecimal(parts[1]), - new BigDecimal(parts[2]) - ); - ps2.addBatch(); - } + for (HumanReadableExportData.DifferentParameterValues entry : meta.differentParameterValues) { + ModelParameterValuesTable.table.bindForInsert(ps2, + + exportHistory.jobID(), + Long.parseLong(user.getID().toString()), + exportHistory.modelRef(), + entry.parameterName(), + new BigDecimal(entry.originalValue()), + new BigDecimal(entry.changedValue()) + ); + ps2.addBatch(); } ps2.executeBatch(); } From fdca277084216d563bddea9c5df9b35d0e2a0858 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 19 Mar 2026 08:42:15 -0400 Subject: [PATCH 34/65] Simulation Ref Instead of Model Ref --- vcell-rest/src/main/resources/scripts/init.sql | 6 +++--- .../java/org/vcell/restq/ExportHistoryTest.java | 14 +++++++++----- .../java/org/vcell/restq/TestEndpointUtils.java | 10 ++++++++++ .../cbit/vcell/modeldb/ExportHistoryDBDriver.java | 4 ++-- .../java/cbit/vcell/modeldb/ExportHistoryRep.java | 2 +- .../cbit/vcell/modeldb/ExportHistoryTable.java | 6 +++--- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index aca585687a..87d9da44e7 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -77,11 +77,11 @@ CREATE TABLE vc_metadata(id bigint PRIMARY KEY,bioModelRef bigint NOT NULL REFER CREATE TABLE vc_simdelfromdisk(deldate varchar(20) ,userid varchar(255) NOT NULL,userkey bigint ,simid bigint ,simpref bigint ,simdate varchar(20) ,simname varchar(255) NOT NULL,status varchar(10) ,numfiles bigint ,totalsize bigint ); CREATE TABLE vc_useridentity(id bigint PRIMARY KEY,userRef bigint NOT NULL REFERENCES vc_userinfo(id),authSubject varchar(128) NOT NULL,authIssuer varchar(128) NOT NULL,insertDate timestamp NOT NULL); -CREATE TABLE vc_model_export_history ( +CREATE TABLE vc_simulation_export_history ( id bigint PRIMARY KEY, job_id bigint NOT NULL, - user_ref bigint NOT NULL REFERENCES vc_userinfo(id) ON DELETE CASCADE, - model_ref bigint NOT NULL REFERENCES vc_model(id) ON DELETE CASCADE, + user_ref bigint NOT NULL REFERENCES vc_userinfo(id), + simulation_ref bigint NOT NULL REFERENCES vc_simulation(id), export_format varchar(50) NOT NULL, export_date timestamp NOT NULL, uri text NOT NULL, diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index 4be8555a34..30ee1bc320 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -6,6 +6,7 @@ import cbit.vcell.modeldb.ExportHistoryDBDriver; import cbit.vcell.modeldb.ExportHistoryRep; import cbit.vcell.resource.PropertyLoader; +import cbit.vcell.solver.Simulation; import cbit.vcell.solver.VCSimulationDataIdentifier; import cbit.vcell.solver.VCSimulationIdentifier; import cbit.vcell.xml.XMLSource; @@ -60,6 +61,8 @@ public class ExportHistoryTest { private DatabaseServerImpl databaseServer; private BioModel savedBioModel; + private Simulation savedSimulation; + private Long simulationKey; private ExportSpecs exportSpecs; @@ -75,7 +78,8 @@ public void createClients() throws ApiException, DataAccessException, PropertyVe BioModel bioModel = TestEndpointUtils.getTestBioModel(); BigString bioModelXML = databaseServer.saveBioModel(TestEndpointUtils.administratorUser, new BigString(XmlHelper.bioModelToXML(bioModel)), new String[]{}); savedBioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelXML.toString())); - + savedSimulation = savedBioModel.getSimulation(0); + simulationKey = Long.parseLong(savedSimulation.getVersion().getVersionKey().toString()); VCSimulationIdentifier vcSimId = new VCSimulationIdentifier( new KeyValue("000"), TestEndpointUtils.administratorUser @@ -145,7 +149,7 @@ public void testAddExportHistory() { user, new ExportHistoryRep( 42L, - Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), + simulationKey, ExportFormat.N5, now, "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", @@ -184,7 +188,7 @@ public void testDeleteExportHistory() throws SQLException { driver.addExportHistory(conn, user, - new ExportHistoryRep(7L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "to-delete", exportSpecs), + new ExportHistoryRep(7L, simulationKey, ExportFormat.N5, now, "to-delete", exportSpecs), agroalConnectionFactory.getKeyFactory() ); @@ -227,11 +231,11 @@ public void testGetExportHistory() throws SQLException, DataAccessException { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); driver.addExportHistory(conn, user, - new ExportHistoryRep(100L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri100", exportSpecs), + new ExportHistoryRep(100L, simulationKey, ExportFormat.N5, now, "uri100", exportSpecs), agroalConnectionFactory.getKeyFactory() ); driver.addExportHistory(conn, user, - new ExportHistoryRep(101L, Long.parseLong(savedBioModel.getModel().getVersion().getVersionKey().toString()), ExportFormat.N5, now, "uri101", exportSpecs), + new ExportHistoryRep(101L, simulationKey, ExportFormat.N5, now, "uri101", exportSpecs), agroalConnectionFactory.getKeyFactory() ); diff --git a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java index 8d008d8664..140f9e48e2 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -111,6 +111,16 @@ public static MathModel getTestMathModel() throws XmlParseException, PropertyVet return mathModel; } + public static Simulation getTestSimulation() throws IOException, XmlParseException, PropertyVetoException { + String vcmlString = IOUtils.toString(TestEndpointUtils.class.getResourceAsStream("/TestVCML.vcml")); + cbit.vcell.biomodel.BioModel bioModel = XmlHelper.XMLToBioModel(new XMLSource(vcmlString)); + bioModel.setName("TestBioModel"); + bioModel.clearVersion(); + Simulation simulation = bioModel.getSimulation(0); + simulation.setName("TestSimulation"); + return simulation; + } + public static Publication defaultPublication(){ Publication publication = new Publication(); publication.setAuthors(Arrays.asList("author1", "author2")); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 0c05e9525a..12caa761d9 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -50,7 +50,7 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export keyValue, exportHistory.jobID(), Long.parseLong(user.getID().toString()), - exportHistory.modelRef(), + exportHistory.simulationRef(), exportHistory.exportFormat(), exportHistory.exportDate(), exportHistory.uri(), @@ -120,7 +120,7 @@ public void deleteExportHistory(Connection conn, ExportSpecs exportSpecs) throws } public ResultSet getExportHistoryForUser(Connection conn, User user) throws SQLException { - String sql = "SELECT * FROM vc_model_export_history WHERE user_ref = ?"; + String sql = "SELECT * FROM vc_simulation_export_history WHERE user_ref = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setLong(1, Long.parseLong(user.getID().toString())); return ps.executeQuery(); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java index 9484717947..f2411d2d79 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java @@ -7,7 +7,7 @@ public record ExportHistoryRep( long jobID, - long modelRef, + long simulationRef, ExportFormat exportFormat, Timestamp exportDate, String uri, diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 3f492b8466..6edccb8461 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -10,7 +10,7 @@ import java.util.StringJoiner; public class ExportHistoryTable extends Table { - private static final String TABLE_NAME = "vc_model_export_history"; + private static final String TABLE_NAME = "vc_simulation_export_history"; // public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); @@ -18,7 +18,7 @@ public class ExportHistoryTable extends Table { public final Field userRef = new Field("user_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + UserTable.REF_TYPE); - public final Field modelRef = new Field("model_ref", Field.SQLDataType.integer, "NOT NULL " + ModelTable.REF_TYPE); + public final Field simulationRef = new Field("simulation_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + SimulationTable.REF_TYPE); public final Field exportFormat = new Field("export_format", Field.SQLDataType.varchar_50, "NOT NULL"); public final Field exportDate = new Field("export_date", Field.SQLDataType.date, "NOT NULL"); @@ -55,7 +55,7 @@ private ExportHistoryTable() { // note that primary key id cannot be placed in fields (will causes class initialization error), Field[] customFields = { // note that primary key id cannot be placed in fields (will causes class initialization error), - jobId, userRef, modelRef, exportFormat, exportDate, uri, dataId, + jobId, userRef, simulationRef, exportFormat, exportDate, uri, dataId, simulationName, applicationName, biomodelName, variables, startTime, endTime, savedFileName, applicationType, nonSpatial, zSlices, tSlices, numVariables From e1be8d35c068aa93c6303f3ac28b736a5b468978 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 19 Mar 2026 08:45:06 -0400 Subject: [PATCH 35/65] Use JSON For Parameter Values Rather than Different Table --- .../src/main/resources/scripts/init.sql | 13 +-- .../src/main/java/cbit/sql/Field.java | 2 + .../vcell/modeldb/ExportHistoryDBDriver.java | 68 +++++++------ .../vcell/modeldb/ExportHistoryTable.java | 5 +- .../modeldb/ModelParameterValuesTable.java | 96 ------------------- 5 files changed, 40 insertions(+), 144 deletions(-) delete mode 100644 vcell-server/src/main/java/cbit/vcell/modeldb/ModelParameterValuesTable.java diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 87d9da44e7..bb70ead9b7 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -90,6 +90,7 @@ CREATE TABLE vc_simulation_export_history ( application_name varchar(255) NOT NULL, biomodel_name varchar(255) NOT NULL, variables text[] NOT NULL, + parameter_values jsonb , start_time numeric NOT NULL, end_time numeric NOT NULL, saved_file_name varchar(255) NOT NULL, @@ -100,15 +101,6 @@ CREATE TABLE vc_simulation_export_history ( num_variables integer NOT NULL DEFAULT 0 ); -CREATE TABLE vc_model_parameter_values( - id bigint PRIMARY KEY REFERENCES vc_model_export_history(id), - user_ref bigint REFERENCES vc_userinfo(id) ON DELETE CASCADE, - model_ref bigint REFERENCES vc_model(id) ON DELETE CASCADE, - parameter_name text NOT NULL, - parameter_original numeric NOT NULL, - parameter_changed numeric NOT NULL -); - CREATE VIEW public.dual AS SELECT CAST('X' as varchar) AS dummy; @@ -120,8 +112,7 @@ CREATE INDEX geom_extentref ON vc_geometry(extentRef); CREATE INDEX geom_imageref ON vc_geometry(imageRef); CREATE INDEX mathdesc_geomref ON vc_math(geometryRef); CREATE INDEX simcstat_simcref ON vc_simcontextstat(simContextRef); -CREATE INDEX idx_export_history_model_ref ON vc_model_export_history(model_ref); -CREATE INDEX idx_param_values_id ON vc_model_parameter_values(id); +CREATE INDEX idx_export_history_simulation_ref ON vc_simulation_export_history(simulation_ref); INSERT INTO vc_userinfo VALUES ( 0,'void','1700596370242','void@example.com','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'B9BDD75BC5382CA83D5AB82172A98D869555899C' ); diff --git a/vcell-server/src/main/java/cbit/sql/Field.java b/vcell-server/src/main/java/cbit/sql/Field.java index b7623636bd..0068eae74b 100644 --- a/vcell-server/src/main/java/cbit/sql/Field.java +++ b/vcell-server/src/main/java/cbit/sql/Field.java @@ -66,6 +66,8 @@ public enum SQLDataType { blob_bytea("blob","bytea",BasicDataType.BLOB), clob_text("clob","text",BasicDataType.CLOB), + + json("clob is json","jsonb", BasicDataType.CLOB), date("date","timestamp",BasicDataType.DATE); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 12caa761d9..da6b604d77 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -1,6 +1,9 @@ package cbit.vcell.modeldb; import cbit.vcell.export.server.*; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.postgresql.util.PGobject; import org.vcell.db.DatabaseSyntax; import org.vcell.db.KeyFactory; import org.vcell.util.DataAccessException; @@ -14,16 +17,6 @@ import java.sql.*; public class ExportHistoryDBDriver { - public static final ExportHistoryTable exportHistoryTable = ExportHistoryTable.table; - public static final ModelParameterValuesTable modelParameterValuesTable = ModelParameterValuesTable.table; - public static final BioModelTable bioModelTable = BioModelTable.table; - public static final PublicationTable publicationTable = PublicationTable.table; - public static final UserTable userTable = UserTable.table; - public static final BioModelSimulationLinkTable bioModelSimLinkTable = BioModelSimulationLinkTable.table; - public static final BioModelSimContextLinkTable bioModelSimContextLinkTable = BioModelSimContextLinkTable.table; - public static final SimulationTable simTable = SimulationTable.table; - public static final SimContextTable simContextTable = SimContextTable.table; - /** * LocalDBManager constructor comment. @@ -32,6 +25,11 @@ public ExportHistoryDBDriver(DatabaseSyntax databaseSyntax, KeyFactory keyFactor } + private boolean isOracleConnection(Connection connection) throws SQLException { + String productName = connection.getMetaData().getDatabaseProductName().toLowerCase(); + return productName.contains("oracle"); + } + public void addExportHistory(Connection conn, User user, ExportHistoryRep exportHistory, KeyFactory keyFactory) throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { @@ -45,6 +43,26 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export // 1) insert into vc_model_export_history String ehSQL = ExportHistoryTable.table.getInsertSQL(); KeyValue keyValue = keyFactory.getNewKey(conn); + + Object jsonDBObjectForParamValues; + try{ + ObjectMapper mapper = new ObjectMapper(); + String jsonVersionOfParamValues = mapper.writeValueAsString(exportHistory.exportSpecs().getHumanReadableExportData().differentParameterValues); + if (isOracleConnection(conn)){ + Clob clob = conn.createClob(); + clob.setString(1, jsonVersionOfParamValues); + jsonDBObjectForParamValues = clob; + } else { + PGobject pGobject = new PGobject(); + pGobject.setType("jsonb"); + pGobject.setValue(jsonVersionOfParamValues); + jsonDBObjectForParamValues = pGobject; + } + } catch (JsonProcessingException e){ + throw new DataAccessException(e); + } + + try (PreparedStatement ps = conn.prepareStatement(ehSQL)) { ExportHistoryTable.table.bindForInsert(ps, keyValue, @@ -59,6 +77,7 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export meta.applicationName, meta.biomodelName, conn.createArrayOf("VARCHAR", exportHistory.exportSpecs().getVariableSpecs().getVariableNames()), + jsonDBObjectForParamValues, BigDecimal.valueOf(ts.getBeginTimeIndex()), BigDecimal.valueOf(ts.getEndTimeIndex()), meta.serverSavedFileName, @@ -74,43 +93,20 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export //ps.executeUpdate(); } - // 2) insert each parameter change - String pvSQL = ModelParameterValuesTable.table.getInsertSQL(); - try (PreparedStatement ps2 = conn.prepareStatement(pvSQL)) { - for (HumanReadableExportData.DifferentParameterValues entry : meta.differentParameterValues) { - ModelParameterValuesTable.table.bindForInsert(ps2, - - exportHistory.jobID(), - Long.parseLong(user.getID().toString()), - exportHistory.modelRef(), - entry.parameterName(), - new BigDecimal(entry.originalValue()), - new BigDecimal(entry.changedValue()) - ); - ps2.addBatch(); - } - ps2.executeBatch(); - } - } public void deleteExportHistory(Connection conn, ExportSpecs exportSpecs) throws SQLException { - String selectSQL = "SELECT id FROM vc_model_export_history WHERE data_id = ?"; + // Concern, data id could mean multiple items get deleted + String selectSQL = "SELECT id FROM vc_simulation_export_history WHERE data_id = ?"; try (PreparedStatement psSel = conn.prepareStatement(selectSQL)) { psSel.setString(1, exportSpecs.getVCDataIdentifier().getID()); try (ResultSet rs = psSel.executeQuery()) { while (rs.next()) { long historyId = rs.getLong(1); - try (PreparedStatement psDelParams = conn.prepareStatement( - "DELETE FROM vc_model_parameter_values WHERE id = ?")) { - psDelParams.setLong(1, historyId); - psDelParams.executeUpdate(); - } - try (PreparedStatement psDelHist = conn.prepareStatement( - "DELETE FROM vc_model_export_history WHERE id = ?")) { + "DELETE FROM vc_simulation_export_history WHERE id = ?")) { psDelHist.setLong(1, historyId); psDelHist.executeUpdate(); } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 6edccb8461..7b88261c21 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -30,6 +30,7 @@ public class ExportHistoryTable extends Table { public final Field biomodelName = new Field("biomodel_name", Field.SQLDataType.varchar_255, "NOT NULL"); public final Field variables = new Field("variables", Field.SQLDataType.varchar_255, "[] NOT NULL"); + public final Field changedParameters = new Field("parameter_values", Field.SQLDataType.json, ""); public final Field startTime = new Field("start_time", Field.SQLDataType.integer_as_numeric, "NOT NULL"); public final Field endTime = new Field("end_time", Field.SQLDataType.integer_as_numeric, "NOT NULL"); public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_255, "NOT NULL"); @@ -56,7 +57,7 @@ private ExportHistoryTable() { Field[] customFields = { // note that primary key id cannot be placed in fields (will causes class initialization error), jobId, userRef, simulationRef, exportFormat, exportDate, uri, dataId, - simulationName, applicationName, biomodelName, variables, + simulationName, applicationName, biomodelName, variables, changedParameters, startTime, endTime, savedFileName, applicationType, nonSpatial, zSlices, tSlices, numVariables }; @@ -92,6 +93,7 @@ public void bindForInsert( String appName, String bioName, Array variables, + Object parameterValues, BigDecimal startTimeValue, BigDecimal endTimeValue, String savedFileNameValue, @@ -114,6 +116,7 @@ public void bindForInsert( ps.setString (i++, appName); ps.setString (i++, bioName); ps.setArray (i++, variables); + ps.setObject (i++, parameterValues); ps.setBigDecimal (i++, startTimeValue); ps.setBigDecimal (i++, endTimeValue); ps.setString (i++, savedFileNameValue); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ModelParameterValuesTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ModelParameterValuesTable.java deleted file mode 100644 index ffb4160f82..0000000000 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ModelParameterValuesTable.java +++ /dev/null @@ -1,96 +0,0 @@ -package cbit.vcell.modeldb; - -import cbit.sql.Field; -import cbit.sql.Table; -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.StringJoiner; - -/** - * Defines the vc_model_parameter_values table and how to read rows from it. - */ -public class ModelParameterValuesTable extends Table { - private static final String TABLE_NAME = "vc_model_parameter_values"; - - /** FK back to vc_model_export_history.id */ - public final Field exportId = new Field("export_id", Field.SQLDataType.integer, "NOT NULL REFERENCES vc_model_export_history(id)"); - public final Field userRef = new Field("user_ref", Field.SQLDataType.integer, "NOT NULL " + UserTable.REF_TYPE); - public final Field modelRef = new Field("model_ref", Field.SQLDataType.integer, "NOT NULL " + ModelTable.REF_TYPE); - public final Field parameterName = new Field("parameter_name", Field.SQLDataType.varchar_50, "NOT NULL"); - public final Field parameterOriginal = new Field("parameter_original", Field.SQLDataType.number_as_real, "NOT NULL"); - public final Field parameterChanged = new Field("parameter_changed", Field.SQLDataType.number_as_real, "NOT NULL"); - - private final Field[] fields = { - exportId, - userRef, - modelRef, - parameterName, - parameterOriginal, - parameterChanged - }; - - private final Field[] insertFields = { - exportId, userRef, modelRef, parameterName, parameterOriginal, parameterChanged - }; - - public static final ModelParameterValuesTable table = new ModelParameterValuesTable(); - - private ModelParameterValuesTable() { - super(TABLE_NAME); - addFields(fields); - } - - - public String getInsertSQL() { - StringJoiner cols = new StringJoiner(",", "(", ")"); - for (Field f : insertFields) { - cols.add(f.getQualifiedColName()); - } - StringJoiner ph = new StringJoiner(",", "(", ")"); - for (int i = 0; i < insertFields.length; i++) { - ph.add("?"); - } - return "INSERT INTO " + TABLE_NAME + " " + cols.toString() + " VALUES " + ph.toString(); - } - - public void bindForInsert( - PreparedStatement ps, - long exportIdValue, - long userRefValue, - long modelRefValue, - String parameterNameValue, - BigDecimal originalValue, - BigDecimal changedValue - ) throws SQLException { - int i=1; - ps.setLong (i++, exportIdValue); - ps.setLong (i++, userRefValue); - ps.setLong (i++, modelRefValue); - ps.setString (i++, parameterNameValue); - ps.setBigDecimal (i++, originalValue); - ps.setBigDecimal (i++, changedValue); - } - - public record ModelParameterValueRecord(long userRef, long modelRef, String parameterName, - BigDecimal parameterOriginal, BigDecimal parameterChanged) { - } - - - public ModelParameterValueRecord getModelParameterValueRecord(ResultSet rset, ModelParameterValueRecord modelParameterValueRecord) throws SQLException { - long userRef = rset.getLong((int) modelParameterValueRecord.userRef); - long modelRef = rset.getLong((int) modelParameterValueRecord.modelRef); - String paramName = rset.getString(parameterName.toString()); - BigDecimal origVal = rset.getBigDecimal(parameterOriginal.toString()); - BigDecimal changedVal = rset.getBigDecimal(parameterChanged.toString()); - - return new ModelParameterValueRecord( - userRef, - modelRef, - paramName, - origVal, - changedVal - ); - } -} From cac209e81572d718de7fad77ebf56cb6aebddb98 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 20 Mar 2026 10:39:03 -0400 Subject: [PATCH 36/65] Expand on Export Specs --- .../org/vcell/restq/ExportHistoryTest.java | 103 ++++++------------ .../vcell/modeldb/ExportHistoryDBDriver.java | 39 +++---- .../cbit/vcell/modeldb/ExportHistoryRep.java | 23 +++- .../vcell/modeldb/ExportHistoryTable.java | 20 ++-- 4 files changed, 79 insertions(+), 106 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index 30ee1bc320..77e37e52c6 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -22,23 +22,17 @@ import org.vcell.restq.db.AgroalConnectionFactory; import org.vcell.util.BigString; import org.vcell.util.DataAccessException; -import org.vcell.util.DependencyException; -import org.vcell.util.ObjectNotFoundException; import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; import org.vcell.util.document.VCDataIdentifier; import cbit.vcell.export.server.ExportFormat; -import cbit.vcell.export.server.ExportSpecs; import java.beans.PropertyVetoException; import java.io.IOException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; +import java.sql.*; import java.time.Instant; import java.util.ArrayList; -import java.util.HashMap; +import java.util.List; import static org.bouncycastle.math.raw.Nat.equalTo; import static org.hamcrest.Matchers.notNullValue; @@ -62,10 +56,7 @@ public class ExportHistoryTest { private DatabaseServerImpl databaseServer; private BioModel savedBioModel; private Simulation savedSimulation; - private Long simulationKey; - - private ExportSpecs exportSpecs; - + private KeyValue simulationKey; @BeforeAll public static void setupConfig(){ @@ -79,56 +70,36 @@ public void createClients() throws ApiException, DataAccessException, PropertyVe BigString bioModelXML = databaseServer.saveBioModel(TestEndpointUtils.administratorUser, new BigString(XmlHelper.bioModelToXML(bioModel)), new String[]{}); savedBioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelXML.toString())); savedSimulation = savedBioModel.getSimulation(0); - simulationKey = Long.parseLong(savedSimulation.getVersion().getVersionKey().toString()); - - VCSimulationIdentifier vcSimId = new VCSimulationIdentifier( - new KeyValue("000"), TestEndpointUtils.administratorUser - ); - VCDataIdentifier vcdId = new VCSimulationDataIdentifier(vcSimId, 0); - + simulationKey = savedSimulation.getVersion().getVersionKey(); + } + private ExportHistoryRep getExportHistoryRep(int jobID, String uri, Timestamp timestamp){ + VCSimulationIdentifier vcSimId = new VCSimulationIdentifier(simulationKey, TestEndpointUtils.administratorUser); + VCDataIdentifier vcdId = new VCSimulationDataIdentifier(vcSimId, jobID); GeometrySpecs geometrySpecs = new GeometrySpecs(null, 1, 1, ExportEnums.GeometryMode.GEOMETRY_FULL); - - double[] times = new double[]{0.0, 1.0}; - TimeSpecs timeSpecs = new TimeSpecs(0, 1, times, ExportEnums.TimeMode.TIME_RANGE); - - + TimeSpecs timeSpecs = new TimeSpecs(0, 1, new double[]{0.0, 1.0}, ExportEnums.TimeMode.TIME_RANGE); VariableSpecs variableSpecs = new VariableSpecs(new String[]{"X"}, ExportEnums.VariableMode.VARIABLE_ONE); + N5Specs n5Specs = new N5Specs(ExportEnums.ExportableDataType.PDE_VARIABLE_DATA, ExportFormat.N5, + N5Specs.CompressionLevel.RAW, "test dataset name"); - FormatSpecificSpecs formatSpecific = new FormatSpecificSpecs("N5") { - @Override public boolean equals(Object o) { return this==o; } - @Override public String toString() { return "DUMMY"; } - }; + List parameterValues = new ArrayList<>(){{ + add(new HumanReadableExportData.DifferentParameterValues("parameter_name", "original_0", "changed_1")); + }}; - HumanReadableExportData meta = new HumanReadableExportData( - "simName", // simulation name - "appName", // application name - savedBioModel.getName(), // biomodel name - new ArrayList(), // no parameter changes - vcdId.getID(), // dataId - "out.n5", // serverSavedFileName - false, // nonSpatial? - new HashMap<>() // no per‐slice parameters + return new ExportHistoryRep( + jobID, vcSimId.getSimulationKey(), n5Specs.getFormatType(), + timestamp, uri, vcdId.getID(), savedSimulation.getName(), + "Application Name", savedBioModel.getName(), variableSpecs.getVariableNames(), + parameterValues, timeSpecs.getAllTimes()[0], timeSpecs.getAllTimes()[1], + "file_on_server", n5Specs.getDataType().name(), false, + 0, 1, 1 ); - - - exportSpecs = new ExportSpecs( - vcdId, - ExportFormat.N5, - variableSpecs, - timeSpecs, - geometrySpecs, - formatSpecific, - "simName", - savedBioModel.getName() - ); - exportSpecs.setExportMetaData(meta); - } + @AfterEach public void removeOIDCMappings() throws SQLException, DataAccessException { TestEndpointUtils.clearAllBioModelEntries(agroalConnectionFactory); @@ -147,31 +118,24 @@ public void testAddExportHistory() { driver.addExportHistory( conn, user, - new ExportHistoryRep( - 42L, - simulationKey, - ExportFormat.N5, - now, + getExportHistoryRep( + 42, "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", - exportSpecs + now ), agroalConnectionFactory.getKeyFactory() ); try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { Assertions.assertTrue(rs.next(), "expected one record"); - Assertions.assertEquals(42L, rs.getLong("job_id")); + Assertions.assertEquals(42L, rs.getInt("job_id")); Assertions.assertEquals("https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", rs.getString("uri")); Assertions.assertEquals("N5", rs.getString("export_format")); Assertions.assertFalse(rs.next(), "only one record should exist"); } catch (SQLException e) { throw new RuntimeException(e); } - } catch (SQLException | ObjectNotFoundException e) { - throw new RuntimeException(e); - } catch (DependencyException e) { - throw new RuntimeException(e); - } catch (DataAccessException e) { + } catch (SQLException | DataAccessException e) { throw new RuntimeException(e); } @@ -185,10 +149,11 @@ public void testDeleteExportHistory() throws SQLException { try (Connection conn = agroalConnectionFactory.getConnection(null)) { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); + ExportHistoryRep exportHistoryRep = getExportHistoryRep(7, "to-delete", now); driver.addExportHistory(conn, user, - new ExportHistoryRep(7L, simulationKey, ExportFormat.N5, now, "to-delete", exportSpecs), + exportHistoryRep, agroalConnectionFactory.getKeyFactory() ); @@ -213,10 +178,6 @@ public void testDeleteExportHistory() throws SQLException { try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { assertFalse(rs.next(),"No rows should remain after deletion"); } - } catch (ObjectNotFoundException e) { - throw new RuntimeException(e); - } catch (DependencyException e) { - throw new RuntimeException(e); } catch (DataAccessException e) { throw new RuntimeException(e); } @@ -229,13 +190,15 @@ public void testGetExportHistory() throws SQLException, DataAccessException { try (Connection conn = agroalConnectionFactory.getConnection(null)) { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); + ExportHistoryRep exportHistoryRep = getExportHistoryRep(100, "uri100", now); + ExportHistoryRep exportHistoryRep1 = getExportHistoryRep(101, "uri101", now); driver.addExportHistory(conn, user, - new ExportHistoryRep(100L, simulationKey, ExportFormat.N5, now, "uri100", exportSpecs), + exportHistoryRep, agroalConnectionFactory.getKeyFactory() ); driver.addExportHistory(conn, user, - new ExportHistoryRep(101L, simulationKey, ExportFormat.N5, now, "uri101", exportSpecs), + exportHistoryRep1, agroalConnectionFactory.getKeyFactory() ); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index da6b604d77..5fae57933d 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -33,13 +33,6 @@ private boolean isOracleConnection(Connection connection) throws SQLException { public void addExportHistory(Connection conn, User user, ExportHistoryRep exportHistory, KeyFactory keyFactory) throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { - ExportSpecs specs = exportHistory.exportSpecs(); - HumanReadableExportData meta = specs.getHumanReadableExportData(); - TimeSpecs ts = specs.getTimeSpecs(); - String[] vars = specs.getVariableSpecs().getVariableNames(); - // comma-separate the variable names - String variablesCsv = String.join(",", vars); - // 1) insert into vc_model_export_history String ehSQL = ExportHistoryTable.table.getInsertSQL(); KeyValue keyValue = keyFactory.getNewKey(conn); @@ -47,7 +40,7 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export Object jsonDBObjectForParamValues; try{ ObjectMapper mapper = new ObjectMapper(); - String jsonVersionOfParamValues = mapper.writeValueAsString(exportHistory.exportSpecs().getHumanReadableExportData().differentParameterValues); + String jsonVersionOfParamValues = mapper.writeValueAsString(exportHistory.parameterValues()); if (isOracleConnection(conn)){ Clob clob = conn.createClob(); clob.setString(1, jsonVersionOfParamValues); @@ -67,25 +60,25 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export ExportHistoryTable.table.bindForInsert(ps, keyValue, exportHistory.jobID(), - Long.parseLong(user.getID().toString()), - exportHistory.simulationRef(), + Integer.parseInt(user.getID().toString()), + Integer.parseInt(exportHistory.simulationRef().toString()), exportHistory.exportFormat(), exportHistory.exportDate(), exportHistory.uri(), - specs.getVCDataIdentifier().getID(), - meta.simulationName, - meta.applicationName, - meta.biomodelName, - conn.createArrayOf("VARCHAR", exportHistory.exportSpecs().getVariableSpecs().getVariableNames()), + exportHistory.dataIdValue(), + exportHistory.simName(), + exportHistory.appName(), + exportHistory.bioName(), + conn.createArrayOf("VARCHAR", exportHistory.variables()), jsonDBObjectForParamValues, - BigDecimal.valueOf(ts.getBeginTimeIndex()), - BigDecimal.valueOf(ts.getEndTimeIndex()), - meta.serverSavedFileName, - meta.applicationType, - meta.nonSpatial, - meta.zSlices, - meta.tSlices, - meta.numChannels + exportHistory.startTimeValue(), + exportHistory.endTimeValue(), + exportHistory.savedFileNameValue(), + exportHistory.applicationTypeValue(), + exportHistory.nonSpatialValue(), + exportHistory.zSlicesValue(), + exportHistory.tSlicesValue(), + exportHistory.numVariablesValue() ); System.out.println("Data insertion tag:"); System.out.println(ps.executeUpdate()); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java index f2411d2d79..bf56cad9d7 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java @@ -2,15 +2,32 @@ import cbit.vcell.export.server.ExportFormat; import cbit.vcell.export.server.ExportSpecs; +import cbit.vcell.export.server.HumanReadableExportData; +import org.vcell.util.document.KeyValue; +import java.math.BigDecimal; import java.sql.Timestamp; +import java.util.List; public record ExportHistoryRep( - long jobID, - long simulationRef, + int jobID, + KeyValue simulationRef, ExportFormat exportFormat, Timestamp exportDate, String uri, - ExportSpecs exportSpecs + String dataIdValue, + String simName, + String appName, + String bioName, + String[] variables, + List parameterValues, + double startTimeValue, + double endTimeValue, + String savedFileNameValue, + String applicationTypeValue, + boolean nonSpatialValue, + int zSlicesValue, + int tSlicesValue, + int numVariablesValue ) { } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 7b88261c21..80e0fb436e 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -31,8 +31,8 @@ public class ExportHistoryTable extends Table { public final Field variables = new Field("variables", Field.SQLDataType.varchar_255, "[] NOT NULL"); public final Field changedParameters = new Field("parameter_values", Field.SQLDataType.json, ""); - public final Field startTime = new Field("start_time", Field.SQLDataType.integer_as_numeric, "NOT NULL"); - public final Field endTime = new Field("end_time", Field.SQLDataType.integer_as_numeric, "NOT NULL"); + public final Field startTime = new Field("start_time", Field.SQLDataType.number_as_real, "NOT NULL"); + public final Field endTime = new Field("end_time", Field.SQLDataType.number_as_real, "NOT NULL"); public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_255, "NOT NULL"); public final Field applicationType = new Field("application_type", Field.SQLDataType.varchar_50, "NOT NULL"); public final Field nonSpatial = new Field("non_spatial", Field.SQLDataType.varchar_50, "NOT NULL"); @@ -82,9 +82,9 @@ public String getInsertSQL() { public void bindForInsert( PreparedStatement ps, KeyValue keyValue, - long jobIdValue, - long userRefValue, - long modelRefValue, + int jobIdValue, + int userRefValue, + int simulationRef, ExportFormat fmt, Timestamp exportDateValue, String uriValue, @@ -94,8 +94,8 @@ public void bindForInsert( String bioName, Array variables, Object parameterValues, - BigDecimal startTimeValue, - BigDecimal endTimeValue, + double startTimeValue, + double endTimeValue, String savedFileNameValue, String applicationTypeValue, boolean nonSpatialValue, @@ -107,7 +107,7 @@ public void bindForInsert( ps.setInt (i++, Integer.parseInt(keyValue.toString())); ps.setLong (i++, jobIdValue); ps.setLong (i++, userRefValue); - ps.setLong (i++, modelRefValue); + ps.setLong (i++, simulationRef); ps.setString (i++, fmt.name()); ps.setTimestamp (i++, exportDateValue); ps.setString (i++, uriValue); @@ -117,8 +117,8 @@ public void bindForInsert( ps.setString (i++, bioName); ps.setArray (i++, variables); ps.setObject (i++, parameterValues); - ps.setBigDecimal (i++, startTimeValue); - ps.setBigDecimal (i++, endTimeValue); + ps.setDouble (i++, startTimeValue); + ps.setDouble (i++, endTimeValue); ps.setString (i++, savedFileNameValue); ps.setString (i++, applicationTypeValue); ps.setBoolean (i++, nonSpatialValue); From fcdff566bd378792a45cef0c31d795e8c6f2615e Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 20 Mar 2026 10:41:16 -0400 Subject: [PATCH 37/65] Delete Entry Based on URI --- .../org/vcell/restq/ExportHistoryTest.java | 19 ++++++------------ .../vcell/modeldb/ExportHistoryDBDriver.java | 20 +++++-------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index 77e37e52c6..b5adf16846 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -101,7 +101,11 @@ private ExportHistoryRep getExportHistoryRep(int jobID, String uri, Timestamp ti @AfterEach - public void removeOIDCMappings() throws SQLException, DataAccessException { + public void cleanUp() throws SQLException, DataAccessException { + String sql = "DELETE FROM VC_SIMULATION_EXPORT_HISTORY"; + Connection connection = agroalConnectionFactory.getConnection(null); + connection.prepareStatement(sql).execute(); + connection.commit(); TestEndpointUtils.clearAllBioModelEntries(agroalConnectionFactory); } @@ -163,18 +167,7 @@ public void testDeleteExportHistory() throws SQLException { Assertions.assertEquals("to-delete", rs.getString("uri")); } - -// driver.deleteExportHistory(conn, exportSpecs); - -// try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { -// Assertions.assertNotEquals("to-delete", rs.getString("uri")); -// Assertions.assertFalse(rs.next()); -// } - - - driver.deleteExportHistory(conn, exportSpecs); - - + driver.deleteExportHistory(conn, exportHistoryRep.uri()); try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { assertFalse(rs.next(),"No rows should remain after deletion"); } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 5fae57933d..620ad12c90 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -88,23 +88,13 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export } - public void deleteExportHistory(Connection conn, ExportSpecs exportSpecs) throws SQLException { + public void deleteExportHistory(Connection conn, String uri) throws SQLException { // Concern, data id could mean multiple items get deleted - String selectSQL = "SELECT id FROM vc_simulation_export_history WHERE data_id = ?"; - try (PreparedStatement psSel = conn.prepareStatement(selectSQL)) { - psSel.setString(1, exportSpecs.getVCDataIdentifier().getID()); - try (ResultSet rs = psSel.executeQuery()) { - while (rs.next()) { - long historyId = rs.getLong(1); - - try (PreparedStatement psDelHist = conn.prepareStatement( - "DELETE FROM vc_simulation_export_history WHERE id = ?")) { - psDelHist.setLong(1, historyId); - psDelHist.executeUpdate(); - } - } - } + String deleteSQL = "DELETE FROM vc_simulation_export_history WHERE uri = ?"; + try (PreparedStatement psDel = conn.prepareStatement(deleteSQL)) { + psDel.setString(1, uri); + psDel.executeUpdate(); } } From d4223387a39990784969424d0bcbfe52c6e3c896 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 20 Mar 2026 11:14:57 -0400 Subject: [PATCH 38/65] Assert That Delete Only Operates on Specified Rows --- .../src/test/java/org/vcell/restq/ExportHistoryTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index b5adf16846..ed0791c405 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -154,21 +154,30 @@ public void testDeleteExportHistory() throws SQLException { try (Connection conn = agroalConnectionFactory.getConnection(null)) { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); ExportHistoryRep exportHistoryRep = getExportHistoryRep(7, "to-delete", now); + ExportHistoryRep notDeletedRep = getExportHistoryRep(8, "to-keep", now); driver.addExportHistory(conn, user, exportHistoryRep, agroalConnectionFactory.getKeyFactory() ); + driver.addExportHistory(conn, user, + notDeletedRep, + agroalConnectionFactory.getKeyFactory() + ); try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { Assertions.assertTrue(rs.next()); Assertions.assertEquals("to-delete", rs.getString("uri")); + Assertions.assertTrue(rs.next()); + Assertions.assertEquals("to-keep", rs.getString("uri")); } driver.deleteExportHistory(conn, exportHistoryRep.uri()); try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { + Assertions.assertTrue(rs.next()); + Assertions.assertEquals("to-keep", rs.getString("uri")); assertFalse(rs.next(),"No rows should remain after deletion"); } } catch (DataAccessException e) { From 4bcd966a6be9111d8330d1867b749e44e18634e1 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 20 Mar 2026 12:25:33 -0400 Subject: [PATCH 39/65] Get Export Returns A List --- .../server/HumanReadableExportData.java | 10 +- .../org/vcell/restq/ExportHistoryTest.java | 69 ++++++-------- .../vcell/modeldb/ExportHistoryDBDriver.java | 12 ++- .../cbit/vcell/modeldb/ExportHistoryRep.java | 21 +++++ .../vcell/modeldb/ExportHistoryTable.java | 92 +++++++++---------- 5 files changed, 110 insertions(+), 94 deletions(-) diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/HumanReadableExportData.java b/vcell-core/src/main/java/cbit/vcell/export/server/HumanReadableExportData.java index 07a9897c0b..4aef5961c0 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/HumanReadableExportData.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/HumanReadableExportData.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.Serializable; import java.util.ArrayList; @@ -14,7 +17,12 @@ public record DifferentParameterValues( String parameterName, String originalValue, String changedValue - ){} + ){ + public static List fromJSON(String json) throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(json, new TypeReference>() {}); + } + } public final String simulationName; public final String biomodelName; diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java index ed0791c405..c57e282e53 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java @@ -12,6 +12,7 @@ import cbit.vcell.xml.XMLSource; import cbit.vcell.xml.XmlHelper; import cbit.vcell.xml.XmlParseException; +import com.fasterxml.jackson.core.JsonProcessingException; import io.quarkus.test.junit.QuarkusTest; import jakarta.inject.Inject; import org.eclipse.microprofile.config.inject.ConfigProperty; @@ -87,6 +88,7 @@ private ExportHistoryRep getExportHistoryRep(int jobID, String uri, Timestamp ti List parameterValues = new ArrayList<>(){{ add(new HumanReadableExportData.DifferentParameterValues("parameter_name", "original_0", "changed_1")); + add(new HumanReadableExportData.DifferentParameterValues("parameter_name2", "original_0", "changed_1")); }}; return new ExportHistoryRep( @@ -117,33 +119,24 @@ public void testAddExportHistory() { try (Connection conn = agroalConnectionFactory.getConnection(null)) { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); - - - driver.addExportHistory( - conn, - user, - getExportHistoryRep( - 42, - "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", - now - ), - agroalConnectionFactory.getKeyFactory() + ExportHistoryRep rep = getExportHistoryRep( + 42, + "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", + now ); - try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { - Assertions.assertTrue(rs.next(), "expected one record"); - Assertions.assertEquals(42L, rs.getInt("job_id")); - Assertions.assertEquals("https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", rs.getString("uri")); - Assertions.assertEquals("N5", rs.getString("export_format")); - Assertions.assertFalse(rs.next(), "only one record should exist"); - } catch (SQLException e) { + driver.addExportHistory(conn, user, rep, agroalConnectionFactory.getKeyFactory()); + try { + List exportHistoryRecord = driver.getExportHistoryForUser(conn, user); + Assertions.assertEquals(1, exportHistoryRecord.size(), "expected one record"); + Assertions.assertTrue(rep.equals(exportHistoryRecord.get(0))); + Assertions.assertEquals(rep.parameterValues(), exportHistoryRecord.get(0).parameterValues()); + } catch (SQLException | JsonProcessingException e) { throw new RuntimeException(e); } } catch (SQLException | DataAccessException e) { throw new RuntimeException(e); } - - } @Test @@ -167,26 +160,22 @@ public void testDeleteExportHistory() throws SQLException { ); - try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { - Assertions.assertTrue(rs.next()); - Assertions.assertEquals("to-delete", rs.getString("uri")); - Assertions.assertTrue(rs.next()); - Assertions.assertEquals("to-keep", rs.getString("uri")); - } + List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + Assertions.assertEquals(2, retrievedExportHistory.size(), "expected two records"); + Assertions.assertTrue(exportHistoryRep.equals(retrievedExportHistory.get(0))); + Assertions.assertTrue(notDeletedRep.equals(retrievedExportHistory.get(1))); driver.deleteExportHistory(conn, exportHistoryRep.uri()); - try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { - Assertions.assertTrue(rs.next()); - Assertions.assertEquals("to-keep", rs.getString("uri")); - assertFalse(rs.next(),"No rows should remain after deletion"); - } - } catch (DataAccessException e) { + retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + Assertions.assertEquals(1, retrievedExportHistory.size(), "expected one record after deletion"); + Assertions.assertTrue(notDeletedRep.equals(retrievedExportHistory.get(0))); + } catch (DataAccessException | JsonProcessingException e) { throw new RuntimeException(e); } } @Test - public void testGetExportHistory() throws SQLException, DataAccessException { + public void testGetExportHistory() throws SQLException, DataAccessException, JsonProcessingException { User user = TestEndpointUtils.administratorUser; Timestamp now = new Timestamp(System.currentTimeMillis()); @@ -204,16 +193,10 @@ public void testGetExportHistory() throws SQLException, DataAccessException { agroalConnectionFactory.getKeyFactory() ); - int count = 0; - try (ResultSet rs = driver.getExportHistoryForUser(conn, user)) { - while (rs.next()) { - count++; - Assertions.assertTrue(rs.getString("uri").startsWith("uri")); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } - Assertions.assertEquals(2, count); + List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + Assertions.assertEquals(2, retrievedExportHistory.size(), "expected two records"); + Assertions.assertTrue(exportHistoryRep.equals(retrievedExportHistory.get(0))); + Assertions.assertTrue(exportHistoryRep1.equals(retrievedExportHistory.get(1))); } } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java index 620ad12c90..932619da08 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java @@ -15,6 +15,8 @@ import java.math.BigDecimal; import java.sql.*; +import java.util.ArrayList; +import java.util.List; public class ExportHistoryDBDriver { @@ -89,7 +91,6 @@ public void addExportHistory(Connection conn, User user, ExportHistoryRep export } public void deleteExportHistory(Connection conn, String uri) throws SQLException { - // Concern, data id could mean multiple items get deleted String deleteSQL = "DELETE FROM vc_simulation_export_history WHERE uri = ?"; try (PreparedStatement psDel = conn.prepareStatement(deleteSQL)) { @@ -98,11 +99,16 @@ public void deleteExportHistory(Connection conn, String uri) throws SQLException } } - public ResultSet getExportHistoryForUser(Connection conn, User user) throws SQLException { + public List getExportHistoryForUser(Connection conn, User user) throws SQLException, JsonProcessingException { String sql = "SELECT * FROM vc_simulation_export_history WHERE user_ref = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setLong(1, Long.parseLong(user.getID().toString())); - return ps.executeQuery(); + ResultSet resultSet = ps.executeQuery(); + List exportHistoryReps = new ArrayList<>(); + while (resultSet.next()) { + exportHistoryReps.add(ExportHistoryTable.table.getExportHistoryRecord(resultSet)); + } + return exportHistoryReps; } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java index bf56cad9d7..5cbf4897bf 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java @@ -30,4 +30,25 @@ public record ExportHistoryRep( int tSlicesValue, int numVariablesValue ) { + public boolean equals(ExportHistoryRep other){ + return this.jobID == other.jobID && + this.simulationRef.equals(other.simulationRef) && + this.exportFormat.equals(other.exportFormat) && + this.exportDate.equals(other.exportDate) && + this.uri.equals(other.uri) && + this.dataIdValue.equals(other.dataIdValue) && + this.simName.equals(other.simName) && + this.appName.equals(other.appName) && + this.bioName.equals(other.bioName) && + List.of(this.variables).equals(List.of(other.variables)) && + this.parameterValues.equals(other.parameterValues) && + Double.compare(this.startTimeValue, other.startTimeValue) == 0 && + Double.compare(this.endTimeValue, other.endTimeValue) == 0 && + this.savedFileNameValue.equals(other.savedFileNameValue) && + this.applicationTypeValue.equals(other.applicationTypeValue) && + this.nonSpatialValue == other.nonSpatialValue && + this.zSlicesValue == other.zSlicesValue && + this.tSlicesValue == other.tSlicesValue && + this.numVariablesValue == other.numVariablesValue; + } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java index 80e0fb436e..e99b1e18b8 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java @@ -3,10 +3,13 @@ import cbit.sql.Field; import cbit.sql.Table; import cbit.vcell.export.server.ExportFormat; +import cbit.vcell.export.server.HumanReadableExportData.DifferentParameterValues; +import com.fasterxml.jackson.core.JsonProcessingException; import org.vcell.util.document.KeyValue; import java.math.BigDecimal; import java.sql.*; +import java.util.List; import java.util.StringJoiner; public class ExportHistoryTable extends Table { @@ -127,51 +130,46 @@ public void bindForInsert( ps.setInt (i++, numVariablesValue); } -// public record ExportHistoryRecord(String jobID, long userRef, long modelRef, ExportFormat format, Timestamp date, -// String uri, String dataID, String simName, String appName, String bioName, -// BigDecimal startTime, BigDecimal endTime, String savedFile, String appType, -// boolean nonSpatial, int zSlices, int tSlices, int numVars) { -// } -// -// public ExportHistoryRecord getExportHistoryRecord(ResultSet rset, ExportHistoryRecord exportHistoryRecord) throws SQLException, SQLException { -// -// long userRef = rset.getLong((int) exportHistoryRecord.userRef); -// long modelRef = rset.getLong((int) exportHistoryRecord.modelRef); -// -// // enums & timestamps -// ExportFormat fmt = ExportFormat.valueOf(rset.getString(exportFormat.toString())); -// Timestamp date = rset.getTimestamp(exportDate.toString()); -// -// // strings -// String jobId = rset.getString(exportHistoryRecord.jobID); -// String uriVal = rset.getString(uri.toString()); -// String dataIdVal = rset.getString(dataId.toString()); -// String simNameVal = rset.getString(simulationName.toString()); -// String appNameVal = rset.getString(applicationName.toString()); -// String bioNameVal = rset.getString(biomodelName.toString()); -// -// // text array of variables -// Array sqlArr = rset.getArray(variables.toString()); -// -// // numeric ranges -// BigDecimal startBt = rset.getBigDecimal(startTime.toString()); -// BigDecimal endBt = rset.getBigDecimal(endTime.toString()); -// -// // more strings & flags -// String savedFileVal = rset.getString(savedFileName.toString()); -// String appTypeVal = rset.getString(applicationType.toString()); -// boolean nonSp = rset.getBoolean(nonSpatial.toString()); -// int zS = rset.getInt(zSlices.toString()); -// int tS = rset.getInt(tSlices.toString()); -// int numV = rset.getInt(numVariables.toString()); -// -// -// -// return new ExportHistoryRecord( -// jobId, userRef, modelRef, fmt, date, -// uriVal, dataIdVal, simNameVal, appNameVal, bioNameVal, -// startBt, endBt, savedFileVal, appTypeVal, -// nonSp, zS, tS, numV -// ); -// } + + public ExportHistoryRep getExportHistoryRecord(ResultSet rset) throws SQLException, SQLException, JsonProcessingException { + + int simulationRef = rset.getInt(this.simulationRef.getUnqualifiedColName()); + + // enums & timestamps + ExportFormat fmt = ExportFormat.valueOf(rset.getString(this.exportFormat.getUnqualifiedColName())); + Timestamp date = rset.getTimestamp(this.exportDate.getUnqualifiedColName()); + + // strings + int jobId = rset.getInt(this.jobId.getUnqualifiedColName()); + String uriVal = rset.getString(this.uri.getUnqualifiedColName()); + String dataIdVal = rset.getString(this.dataId.getUnqualifiedColName()); + String simNameVal = rset.getString(this.simulationName.getUnqualifiedColName()); + String appNameVal = rset.getString(this.applicationName.getUnqualifiedColName()); + String bioNameVal = rset.getString(this.biomodelName.getUnqualifiedColName()); + + // text array of variables + String[] variables = (String[]) rset.getArray(this.variables.getUnqualifiedColName()).getArray(); + List parameterValues = DifferentParameterValues.fromJSON(rset.getString(this.changedParameters.getUnqualifiedColName())); + + // numeric ranges + double startBt = rset.getDouble(this.startTime.getUnqualifiedColName()); + double endBt = rset.getDouble(this.endTime.getUnqualifiedColName()); + + // more strings & flags + String savedFileVal = rset.getString(this.savedFileName.getUnqualifiedColName()); + String appTypeVal = rset.getString(this.applicationType.getUnqualifiedColName()); + boolean nonSp = rset.getBoolean(this.nonSpatial.getUnqualifiedColName()); + int zS = rset.getInt(this.zSlices.getUnqualifiedColName()); + int tS = rset.getInt(this.tSlices.getUnqualifiedColName()); + int numV = rset.getInt(this.numVariables.getUnqualifiedColName()); + + + + return new ExportHistoryRep( + jobId, new KeyValue("" + simulationRef), fmt, date, + uriVal, dataIdVal, simNameVal, appNameVal, bioNameVal, variables, + parameterValues, startBt, endBt, savedFileVal, appTypeVal, + nonSp, zS, tS, numV + ); + } } From 68537453b39a7c7f009119d2f2d05a0639840007 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 20 Mar 2026 13:06:39 -0400 Subject: [PATCH 40/65] Relocate Export History Test --- .../ExportHistoryDBTest.java} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename vcell-rest/src/test/java/org/vcell/restq/{ExportHistoryTest.java => exports/ExportHistoryDBTest.java} (98%) diff --git a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java similarity index 98% rename from vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java rename to vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index c57e282e53..b9572a6d8a 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/ExportHistoryTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -1,4 +1,4 @@ -package org.vcell.restq; +package org.vcell.restq.exports; import cbit.vcell.biomodel.BioModel; import cbit.vcell.export.server.*; @@ -19,6 +19,7 @@ import org.junit.jupiter.api.*; import org.vcell.restclient.ApiClient; import org.vcell.restclient.ApiException; +import org.vcell.restq.TestEndpointUtils; import org.vcell.restq.config.CDIVCellConfigProvider; import org.vcell.restq.db.AgroalConnectionFactory; import org.vcell.util.BigString; @@ -38,12 +39,11 @@ import static org.bouncycastle.math.raw.Nat.equalTo; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertEquals; -import static org.vcell.util.VCAssert.assertFalse; import static org.vcell.util.VCAssert.assertTrue; // TODO: Use GenericVCMLTests class for the principle tests for VCDocuments @QuarkusTest -public class ExportHistoryTest { +public class ExportHistoryDBTest { @ConfigProperty(name = "quarkus.http.test-port") Integer testPort; From 53ea4bdfd65e7ee049bb30333cc6262318563b0f Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 23 Mar 2026 10:23:06 -0400 Subject: [PATCH 41/65] Update Export Request Test --- .../org/vcell/restq/TestEndpointUtils.java | 13 +++ .../org/vcell/restq/exports/ExportHelper.java | 105 ++++++++++++++++++ .../restq/exports/ExportRequestTest.java | 75 +------------ 3 files changed, 123 insertions(+), 70 deletions(-) create mode 100644 vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java diff --git a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java index 140f9e48e2..1f4e94facf 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -11,6 +11,9 @@ import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.parser.Expression; import cbit.vcell.resource.PropertyLoader; +import cbit.vcell.simdata.Cachetable; +import cbit.vcell.simdata.DataServerImpl; +import cbit.vcell.simdata.DataSetControllerImpl; import cbit.vcell.solver.Simulation; import cbit.vcell.solver.TimeBounds; import cbit.vcell.xml.XMLSource; @@ -27,6 +30,7 @@ import org.vcell.restclient.model.Publication; import org.vcell.restclient.model.UserLoginInfoForMapping; import org.vcell.restq.db.AgroalConnectionFactory; +import org.vcell.restq.exports.ExportRequestTest; import org.vcell.util.BigString; import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; @@ -34,6 +38,7 @@ import java.beans.PropertyVetoException; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; @@ -169,6 +174,14 @@ public static String getResourceString(String relativeResourcePath) throws IOExc return IOUtils.toString(inputStream); } + public static DataServerImpl createDataServerImpl() throws FileNotFoundException { + File testSimData = new File(ExportRequestTest.class.getResource("/simdata").getPath()); + TestEndpointUtils.setSystemProperties(testSimData.getAbsolutePath(), System.getProperty("java.io.tmpdir")); + Cachetable cachetable = new Cachetable(10 * Cachetable.minute, 10000); + DataSetControllerImpl dataSetController = new DataSetControllerImpl(cachetable, testSimData, testSimData); + return new DataServerImpl(dataSetController, null); + } + /** * Empties out all BioModel, Geometry, math, and simulation related tables */ diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java new file mode 100644 index 0000000000..583fb67583 --- /dev/null +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java @@ -0,0 +1,105 @@ +package org.vcell.restq.exports; + +import cbit.vcell.export.server.ExportEnums; +import cbit.vcell.math.VariableType; +import cbit.vcell.simdata.*; +import cbit.vcell.simdata.DataIdentifier; +import cbit.vcell.solver.AnnotatedFunction; +import cbit.vcell.solver.Simulation; +import cbit.vcell.solver.VCSimulationDataIdentifier; +import cbit.vcell.solver.VCSimulationIdentifier; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Assertions; +import org.vcell.restclient.ApiException; +import org.vcell.restclient.api.ExportResourceApi; +import org.vcell.restclient.model.*; +import org.vcell.restq.TestEndpointUtils; +import org.vcell.util.document.KeyValue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +public class ExportHelper { + private static final Logger lg = LogManager.getLogger(ExportRequestTest.class); + + public static void exportAndWait(ExportResourceApi exportResourceApi, N5ExportRequest n5ExportRequest) throws ApiException { + final long time = Instant.now().getEpochSecond(); // Before export even starts, so that all events are grabbed from the queue + long jobId = exportResourceApi.exportN5(n5ExportRequest); + CompletableFuture future = CompletableFuture.runAsync(() -> { + try{ + List allEvents = new ArrayList<>(); + while (allEvents.isEmpty()){ + Thread.sleep(100); + allEvents = exportResourceApi.exportStatus(time); + lg.debug("The number of events found for time {} is 0. Retrying...", time); + } + ExportEvent eventUnderInspection = getLastEventForJob(allEvents, jobId); +// Assertions.assertEquals(ExportEnums.ExportProgressType.EXPORT_ASSEMBLING, ExportEnums.ExportProgressType.valueOf(eventUnderInspection.getEventType().getValue())); + while (ExportEnums.ExportProgressType.valueOf(eventUnderInspection.getEventType().getValue()) != ExportEnums.ExportProgressType.EXPORT_COMPLETE){ + allEvents = exportResourceApi.exportStatus(time); + lg.debug("The events retrieved are: {}", allEvents); + eventUnderInspection = getLastEventForJob(allEvents, jobId); + lg.debug("The event under inspection is: {}", eventUnderInspection); + Thread.sleep(500); + } + Assertions.assertEquals(ExportProgressType.COMPLETE, eventUnderInspection.getEventType()); + } catch (Exception e){ + Assertions.fail(); + } + }).orTimeout(20, TimeUnit.SECONDS); + future.join(); + } + + private static ExportEvent getLastEventForJob(List events, long jobId){ + for (int i = events.size() - 1; i >= 0; i--){ + ExportEvent event = events.get(i); + if(event.getJobID() == jobId){ + return event; + } + } + throw new RuntimeException("Cannot find event for job id " + jobId); + } + + public static N5ExportRequest getValidExportRequestDTO(int startTimeIndex, int endTimeIndex, + DataServerImpl dataServer, String simulationID) throws Exception { + VCSimulationIdentifier vcSimulationIdentifier = new VCSimulationIdentifier(new KeyValue(simulationID), TestEndpointUtils.administratorUser); + VCSimulationDataIdentifier simulationDataIdentifier = new VCSimulationDataIdentifier(vcSimulationIdentifier, 0); + DataIdentifier[] dataIdentifier = dataServer.getDataIdentifiers(new OutputContext(new AnnotatedFunction[0]), TestEndpointUtils.administratorUser, simulationDataIdentifier); + DataIdentifier volumetricDataID = getOneDIWithSpecificType(VariableType.VOLUME, dataIdentifier); + double[] allTimes = dataServer.getDataSetTimes(TestEndpointUtils.administratorUser, simulationDataIdentifier); + StandardExportInfo exportRequest = new StandardExportInfo() + .simulationKey(simulationID) + .simulationJob(0) + .geometrySpecs(new GeometrySpecDTO().geometryMode(GeometryMode.SELECTIONS).selections(new ArrayList<>())) + .timeSpecs( + new org.vcell.restclient.model.TimeSpecs().beginTimeIndex(startTimeIndex).endTimeIndex(endTimeIndex).allTimes(Arrays.stream(allTimes).boxed().toList()).mode(TimeMode.RANGE) + ) + .variableSpecs( + new org.vcell.restclient.model.VariableSpecs().variableNames(new ArrayList<>(){{add(volumetricDataID.getName());}}).mode(VariableMode.ONE) + ) + .contextName("") + .simulationName(vcSimulationIdentifier.getID()) + .outputContext(new ArrayList<>()); + + return new N5ExportRequest().standardExportInformation(exportRequest) + .exportableDataType(ExportableDataType.PDE_VARIABLE_DATA) + .datasetName("testExport") + .subVolume(new java.util.HashMap<>()); + } + + private static DataIdentifier getOneDIWithSpecificType(VariableType variableType, DataIdentifier[] dataIdentifiers){ + for(DataIdentifier dataIdentifier: dataIdentifiers){ + if(dataIdentifier.getVariableType().equals(variableType)){ + return dataIdentifier; + } + } + throw new RuntimeException("Cannot find variable type " + variableType); + } +} diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java index 6b170510a6..19672645b0 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java @@ -39,6 +39,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import static org.vcell.restq.exports.ExportHelper.getValidExportRequestDTO; + @QuarkusTest public class ExportRequestTest { @ConfigProperty(name = "quarkus.http.test-port") @@ -46,8 +48,6 @@ public class ExportRequestTest { @Inject AgroalConnectionFactory agroalConnectionFactory; - private static final Logger lg = LogManager.getLogger(ExportRequestTest.class); - KeycloakTestClient keycloakClient = new KeycloakTestClient(); private DataServerImpl dataServer; @@ -64,12 +64,7 @@ public void setUp() throws IOException, DataAccessException, ApiException, SQLEx aliceAPIClient = TestEndpointUtils.createAuthenticatedAPIClient(keycloakClient, testPort, TestEndpointUtils.TestOIDCUsers.alice); TestEndpointUtils.mapApiClientToAdmin(aliceAPIClient); DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); - - File testSimData = new File(ExportRequestTest.class.getResource("/simdata").getPath()); - TestEndpointUtils.setSystemProperties(testSimData.getAbsolutePath(), System.getProperty("java.io.tmpdir")); - Cachetable cachetable = new Cachetable(10 * Cachetable.minute, 10000); - DataSetControllerImpl dataSetController = new DataSetControllerImpl(cachetable, testSimData, testSimData); - dataServer = new DataServerImpl(dataSetController, null); + dataServer = TestEndpointUtils.createDataServerImpl(); TestEndpointUtils.insertAdminsSimulation(databaseServer, agroalConnectionFactory); } @@ -82,69 +77,9 @@ public void removeOIDCMappings() throws SQLException, DataAccessException { // Tests the clients capability to submit exports, our queue for accepting and distributing messages, retrieval of export status, and the export job itself @Test public void testExportRequestClient() throws Exception { - final long time = Instant.now().getEpochSecond(); // Before export even starts, so that all events are grabbed from the queue ExportResourceApi exportResourceApi = new ExportResourceApi(aliceAPIClient); - N5ExportRequest exportRequest = getValidExportRequestDTO(0, 1); - exportResourceApi.exportN5(exportRequest); - - CompletableFuture future = CompletableFuture.runAsync(() -> { - try{ - List allEvents = new ArrayList<>(); - while (allEvents.isEmpty()){ - Thread.sleep(100); - allEvents = exportResourceApi.exportStatus(time); - lg.debug("The number of events found for time {} is 0. Retrying...", time); - } - ExportEvent eventUnderInspection = allEvents.stream().toList().get(0); - Assertions.assertEquals(ExportEnums.ExportProgressType.EXPORT_ASSEMBLING, ExportEnums.ExportProgressType.valueOf(eventUnderInspection.getEventType().getValue())); - while (ExportEnums.ExportProgressType.valueOf(eventUnderInspection.getEventType().getValue()) != ExportEnums.ExportProgressType.EXPORT_COMPLETE){ - allEvents = exportResourceApi.exportStatus(time); - lg.debug("The events retrieved are: {}", allEvents); - eventUnderInspection = allEvents.stream().toList().get(allEvents.size() - 1); - lg.debug("The event under inspection is: {}", eventUnderInspection); - Thread.sleep(500); - } - Assertions.assertEquals(ExportProgressType.COMPLETE, eventUnderInspection.getEventType()); - } catch (Exception e){ - Assertions.fail(); - } - }).orTimeout(20, TimeUnit.SECONDS); - future.join(); - } - - private N5ExportRequest getValidExportRequestDTO(int startTimeIndex, int endTimeIndex) throws Exception { - VCSimulationIdentifier vcSimulationIdentifier = new VCSimulationIdentifier(new KeyValue(simulationID), TestEndpointUtils.administratorUser); - VCSimulationDataIdentifier simulationDataIdentifier = new VCSimulationDataIdentifier(vcSimulationIdentifier, 0); - DataIdentifier[] dataIdentifier = dataServer.getDataIdentifiers(new OutputContext(new AnnotatedFunction[0]), TestEndpointUtils.administratorUser, simulationDataIdentifier); - DataIdentifier volumetricDataID = getOneDIWithSpecificType(VariableType.VOLUME, dataIdentifier); - double[] allTimes = dataServer.getDataSetTimes(TestEndpointUtils.administratorUser, simulationDataIdentifier); - StandardExportInfo exportRequest = new StandardExportInfo() - .simulationKey(simulationID) - .simulationJob(0) - .geometrySpecs(new GeometrySpecDTO().geometryMode(GeometryMode.SELECTIONS).selections(new ArrayList<>())) - .timeSpecs( - new org.vcell.restclient.model.TimeSpecs().beginTimeIndex(startTimeIndex).endTimeIndex(endTimeIndex).allTimes(Arrays.stream(allTimes).boxed().toList()).mode(TimeMode.RANGE) - ) - .variableSpecs( - new org.vcell.restclient.model.VariableSpecs().variableNames(new ArrayList<>(){{add(volumetricDataID.getName());}}).mode(VariableMode.ONE) - ) - .contextName("") - .simulationName(vcSimulationIdentifier.getID()) - .outputContext(new ArrayList<>()); - - return new N5ExportRequest().standardExportInformation(exportRequest) - .exportableDataType(ExportableDataType.PDE_VARIABLE_DATA) - .datasetName("testExport") - .subVolume(new java.util.HashMap<>()); - } - - private DataIdentifier getOneDIWithSpecificType(VariableType variableType, DataIdentifier[] dataIdentifiers){ - for(DataIdentifier dataIdentifier: dataIdentifiers){ - if(dataIdentifier.getVariableType().equals(variableType)){ - return dataIdentifier; - } - } - throw new RuntimeException("Cannot find variable type " + variableType); + N5ExportRequest exportRequest = getValidExportRequestDTO(0, 1, dataServer, simulationID); + ExportHelper.exportAndWait(exportResourceApi, exportRequest); } } From d851a0ef197eca3e46c23e794d15edd6beac6c55 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 23 Mar 2026 13:49:02 -0400 Subject: [PATCH 42/65] Return a List of Export History --- .../vcell/restq/handlers/ExportResource.java | 44 ++++++++++++++----- .../restq/services/Exports/ExportService.java | 14 +++++- .../java/cbit/vcell/modeldb/DBTopLevel.java | 25 +++++++++++ .../vcell/modeldb/DatabaseServerImpl.java | 10 +++++ 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java index 6cd734ce8b..6095877f99 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java +++ b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java @@ -5,6 +5,7 @@ import cbit.vcell.export.server.*; import cbit.vcell.math.Variable; import cbit.vcell.math.VariableType; +import cbit.vcell.modeldb.ExportHistoryRep; import cbit.vcell.simdata.SpatialSelection; import cbit.vcell.solver.AnnotatedFunction; import com.fasterxml.jackson.core.JsonProcessingException; @@ -25,9 +26,11 @@ import org.vcell.restq.services.UserRestService; import org.vcell.util.DataAccessException; import org.vcell.util.ObjectNotFoundException; +import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; import java.sql.SQLException; +import java.sql.Timestamp; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -51,8 +54,8 @@ public class ExportResource { @Path("/history") @GET @RolesAllowed("user") - @Operation(operationId = "getExportHistory", hidden = true) - public ExportHistory getExportHistory() throws DataAccessWebException, NotAuthenticatedWebException { + @Operation(operationId = "getExportHistory") + public List getExportHistory() throws DataAccessWebException, NotAuthenticatedWebException { User user = userRestService.getUserFromIdentity(securityIdentity); try { return exportService.getExportHistory(user); @@ -65,13 +68,9 @@ public ExportHistory getExportHistory() throws DataAccessWebException, NotAuthen @DELETE @RolesAllowed("user") @Operation(operationId = "deleteExportHistory", hidden = true) - public ExportHistory deleteExportHistoryEntry() throws DataAccessWebException, NotAuthenticatedWebException { + public void deleteExportHistoryEntry() throws DataAccessWebException, NotAuthenticatedWebException { User user = userRestService.getUserFromIdentity(securityIdentity); - try { - return exportService.getExportHistory(user); - } catch (DataAccessException e) { - throw new DataAccessWebException(e.getMessage(), e); - } + return; } @Path("/status") @@ -146,8 +145,33 @@ public record AnnotatedFunctionDTO( ) { } public record ExportHistory( - String exportHistory - ){ } + int jobID, + KeyValue simulationRef, + ExportFormat exportFormat, + String exportDate, + String uri, + String dataIdValue, + String simName, + String appName, + String bioName, + String[] variables, + List parameterValues, + double startTimeValue, + double endTimeValue, + String savedFileNameValue, + String applicationTypeValue, + boolean nonSpatialValue, + int zSlicesValue, + int tSlicesValue, + int numVariablesValue + ){ + public static ExportHistory fromExportHistoryRep(ExportHistoryRep rep){ + return new ExportHistory(rep.jobID(), rep.simulationRef(), rep.exportFormat(), rep.exportDate().toString(), rep.uri(), rep.dataIdValue(), + rep.simName(), rep.appName(), rep.bioName(), rep.variables(), rep.parameterValues(), rep.startTimeValue(), + rep.endTimeValue(), rep.savedFileNameValue(), rep.applicationTypeValue(), rep.nonSpatialValue(), + rep.zSlicesValue(), rep.tSlicesValue(), rep.numVariablesValue()); + } + } public record GeometrySpecDTO( SpatialSelection[] selections, int axis, int sliceNumber, ExportEnums.GeometryMode geometryMode diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java index d680d095e1..5704be33c6 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java @@ -5,6 +5,8 @@ import cbit.vcell.export.server.ExportFormat; import cbit.vcell.export.server.FormatSpecificSpecs; import cbit.vcell.export.server.JobRequest; +import cbit.vcell.modeldb.DatabaseServerImpl; +import cbit.vcell.modeldb.ExportHistoryRep; import cbit.vcell.modeldb.SimulationRep; import cbit.vcell.parser.Expression; import cbit.vcell.parser.ExpressionException; @@ -16,6 +18,7 @@ import jakarta.enterprise.inject.Instance; import jakarta.inject.Inject; import org.vcell.restq.activemq.ExportRequestListenerMQ; +import org.vcell.restq.db.AgroalConnectionFactory; import org.vcell.restq.errors.exceptions.RuntimeWebException; import org.vcell.restq.handlers.ExportResource; import org.vcell.restq.services.SimulationRestService; @@ -40,8 +43,15 @@ public class ExportService { @Inject SimulationRestService simulationRestService; - public ExportResource.ExportHistory getExportHistory(User user) throws DataAccessException { - return new ExportResource.ExportHistory("Hello"); + DatabaseServerImpl databaseServer; + @Inject + public ExportService(AgroalConnectionFactory connectionFactory) throws DataAccessException { + databaseServer = new DatabaseServerImpl(connectionFactory, connectionFactory.getKeyFactory()); + } + + public List getExportHistory(User user) throws DataAccessException { + List exportHistoryReps = databaseServer.getUsersExportHistory(user); + return exportHistoryReps.stream().map(ExportResource.ExportHistory::fromExportHistoryRep).toList(); } public Multi getExportStatuses(User user, long jobID) throws ObjectNotFoundException { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index eebd0b0878..c207e65f7d 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -38,6 +38,7 @@ import java.sql.Connection; import java.sql.SQLException; +import java.util.List; import java.util.TreeMap; import java.util.Vector; /** @@ -2280,4 +2281,28 @@ public void insertExportHistory(User user, ExportHistoryRep exportHistoryValues, } } + public List getUsersExportHistory(User user, boolean bEnableRetry) throws SQLException, DataAccessException { + Object lock = new Object(); + Connection con = conFactory.getConnection(lock); + try { + return exportHistoryDBDriver.getExportHistoryForUser(con, user); + } catch (Throwable e) { + lg.error(e.getMessage(),e); + try { + con.rollback(); + }catch (Throwable rbe){ + lg.error("exception during rollback, bEnableRetry = "+bEnableRetry, rbe); + } + if (bEnableRetry && isBadConnection(con)) { + conFactory.failed(con,lock); + return getUsersExportHistory(user, false); + }else{ + handle_DataAccessException_SQLException(e); + return null; // never gets here; + } + }finally{ + conFactory.release(con,lock); + } + } + } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java index 874b49150c..969c723939 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java @@ -1362,4 +1362,14 @@ public void addExportHistory(User user, ExportHistoryRep exportHistory) throws D throw new DataAccessException(e); } } + + public List getUsersExportHistory(User user) throws DataAccessException { + try { + return dbTop.getUsersExportHistory(user, true); + } catch (SQLException e) { + throw new DataAccessException(e); + } + } + + } From a2ec3dc46df294eb5bb5da4fe5d5037d6cfa8de9 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 23 Mar 2026 13:49:59 -0400 Subject: [PATCH 43/65] Generated Clients --- python-restclient/.openapi-generator/FILES | 9 + python-restclient/README.md | 4 + .../docs/DifferentParameterValues.md | 30 + python-restclient/docs/ExportFormat.md | 10 + python-restclient/docs/ExportHistory.md | 46 + python-restclient/docs/ExportResourceApi.md | 68 ++ .../docs/HumanReadableExportData.md | 2 +- .../test/test_different_parameter_values.py | 55 ++ python-restclient/test/test_export_format.py | 35 + python-restclient/test/test_export_history.py | 78 ++ python-restclient/vcell_client/__init__.py | 3 + .../vcell_client/api/export_resource_api.py | 254 ++++++ .../vcell_client/models/__init__.py | 3 + .../models/different_parameter_values.py | 98 +++ .../vcell_client/models/export_format.py | 56 ++ .../vcell_client/models/export_history.py | 139 +++ .../models/human_readable_export_data.py | 12 +- tools/openapi.yaml | 108 ++- vcell-restclient/.openapi-generator/FILES | 9 + vcell-restclient/README.md | 5 + vcell-restclient/api/openapi.yaml | 157 +++- .../docs/DifferentParameterValues.md | 15 + vcell-restclient/docs/ExportFormat.md | 33 + vcell-restclient/docs/ExportHistory.md | 31 + vcell-restclient/docs/ExportResourceApi.md | 134 +++ .../docs/HumanReadableExportData.md | 2 +- .../restclient/api/ExportResourceApi.java | 66 ++ .../model/DifferentParameterValues.java | 222 +++++ .../vcell/restclient/model/ExportFormat.java | 98 +++ .../vcell/restclient/model/ExportHistory.java | 827 ++++++++++++++++++ .../model/HumanReadableExportData.java | 18 +- .../model/DifferentParameterValuesTest.java | 64 ++ .../restclient/model/ExportFormatTest.java | 32 + .../restclient/model/ExportHistoryTest.java | 196 +++++ .../modules/openapi/.openapi-generator/FILES | 3 + .../openapi/api/export-resource.service.ts | 61 ++ .../api/export-resource.serviceInterface.ts | 7 + .../model/different-parameter-values.ts | 19 + .../modules/openapi/model/export-format.ts | 30 + .../modules/openapi/model/export-history.ts | 40 + .../model/human-readable-export-data.ts | 3 +- .../app/core/modules/openapi/model/models.ts | 3 + 42 files changed, 3066 insertions(+), 19 deletions(-) create mode 100644 python-restclient/docs/DifferentParameterValues.md create mode 100644 python-restclient/docs/ExportFormat.md create mode 100644 python-restclient/docs/ExportHistory.md create mode 100644 python-restclient/test/test_different_parameter_values.py create mode 100644 python-restclient/test/test_export_format.py create mode 100644 python-restclient/test/test_export_history.py create mode 100644 python-restclient/vcell_client/models/different_parameter_values.py create mode 100644 python-restclient/vcell_client/models/export_format.py create mode 100644 python-restclient/vcell_client/models/export_history.py create mode 100644 vcell-restclient/docs/DifferentParameterValues.md create mode 100644 vcell-restclient/docs/ExportFormat.md create mode 100644 vcell-restclient/docs/ExportHistory.md create mode 100644 vcell-restclient/src/main/java/org/vcell/restclient/model/DifferentParameterValues.java create mode 100644 vcell-restclient/src/main/java/org/vcell/restclient/model/ExportFormat.java create mode 100644 vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java create mode 100644 vcell-restclient/src/test/java/org/vcell/restclient/model/DifferentParameterValuesTest.java create mode 100644 vcell-restclient/src/test/java/org/vcell/restclient/model/ExportFormatTest.java create mode 100644 vcell-restclient/src/test/java/org/vcell/restclient/model/ExportHistoryTest.java create mode 100644 webapp-ng/src/app/core/modules/openapi/model/different-parameter-values.ts create mode 100644 webapp-ng/src/app/core/modules/openapi/model/export-format.ts create mode 100644 webapp-ng/src/app/core/modules/openapi/model/export-history.ts diff --git a/python-restclient/.openapi-generator/FILES b/python-restclient/.openapi-generator/FILES index bd03d3b283..8ff2641798 100644 --- a/python-restclient/.openapi-generator/FILES +++ b/python-restclient/.openapi-generator/FILES @@ -19,8 +19,11 @@ docs/Curve.md docs/CurveSelectionInfo.md docs/DataIdentifier.md docs/DetailedState.md +docs/DifferentParameterValues.md docs/Domain.md docs/ExportEvent.md +docs/ExportFormat.md +docs/ExportHistory.md docs/ExportProgressType.md docs/ExportResourceApi.md docs/ExportableDataType.md @@ -99,6 +102,9 @@ docs/VariableType.md docs/Version.md docs/VersionFlag.md test/__init__.py +test/test_different_parameter_values.py +test/test_export_format.py +test/test_export_history.py tox.ini vcell_client/__init__.py vcell_client/api/__init__.py @@ -135,8 +141,11 @@ vcell_client/models/curve.py vcell_client/models/curve_selection_info.py vcell_client/models/data_identifier.py vcell_client/models/detailed_state.py +vcell_client/models/different_parameter_values.py vcell_client/models/domain.py vcell_client/models/export_event.py +vcell_client/models/export_format.py +vcell_client/models/export_history.py vcell_client/models/export_progress_type.py vcell_client/models/exportable_data_type.py vcell_client/models/extent.py diff --git a/python-restclient/README.md b/python-restclient/README.md index 9f03577c84..c91772ead2 100644 --- a/python-restclient/README.md +++ b/python-restclient/README.md @@ -98,6 +98,7 @@ Class | Method | HTTP request | Description *BioModelResourceApi* | [**save_bio_model**](docs/BioModelResourceApi.md#save_bio_model) | **POST** /api/v1/bioModel | Save's the given BioModel. Optional parameters of name and simulations to update due to math changes. Returns saved BioModel as VCML. *ExportResourceApi* | [**export_n5**](docs/ExportResourceApi.md#export_n5) | **POST** /api/v1/export/N5 | *ExportResourceApi* | [**export_status**](docs/ExportResourceApi.md#export_status) | **GET** /api/v1/export/status | +*ExportResourceApi* | [**get_export_history**](docs/ExportResourceApi.md#get_export_history) | **GET** /api/v1/export/history | *FieldDataResourceApi* | [**advanced_create**](docs/FieldDataResourceApi.md#advanced_create) | **POST** /api/v1/fieldData/advancedCreate | Create Field Data with granular detail in one request.The following files are accepted: .tif and .zip. *FieldDataResourceApi* | [**analyze_file**](docs/FieldDataResourceApi.md#analyze_file) | **POST** /api/v1/fieldData/analyzeFile | Analyze uploaded image file (Tiff, Zip, and Non-GPL BioFormats) and return field data. Color mapped images not supported (the colors in those images will be interpreted as separate channels). Filenames must be lowercase alphanumeric, and can contain underscores. *FieldDataResourceApi* | [**copy_models_field_data**](docs/FieldDataResourceApi.md#copy_models_field_data) | **POST** /api/v1/fieldData/copyModelsFieldData | Copy all existing field data from a BioModel/MathModel that you have access to, but don't own. @@ -163,8 +164,11 @@ Class | Method | HTTP request | Description - [CurveSelectionInfo](docs/CurveSelectionInfo.md) - [DataIdentifier](docs/DataIdentifier.md) - [DetailedState](docs/DetailedState.md) + - [DifferentParameterValues](docs/DifferentParameterValues.md) - [Domain](docs/Domain.md) - [ExportEvent](docs/ExportEvent.md) + - [ExportFormat](docs/ExportFormat.md) + - [ExportHistory](docs/ExportHistory.md) - [ExportProgressType](docs/ExportProgressType.md) - [ExportableDataType](docs/ExportableDataType.md) - [Extent](docs/Extent.md) diff --git a/python-restclient/docs/DifferentParameterValues.md b/python-restclient/docs/DifferentParameterValues.md new file mode 100644 index 0000000000..1451490b86 --- /dev/null +++ b/python-restclient/docs/DifferentParameterValues.md @@ -0,0 +1,30 @@ +# DifferentParameterValues + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**parameter_name** | **str** | | [optional] +**original_value** | **str** | | [optional] +**changed_value** | **str** | | [optional] + +## Example + +```python +from vcell_client.models.different_parameter_values import DifferentParameterValues + +# TODO update the JSON string below +json = "{}" +# create an instance of DifferentParameterValues from a JSON string +different_parameter_values_instance = DifferentParameterValues.from_json(json) +# print the JSON string representation of the object +print DifferentParameterValues.to_json() + +# convert the object into a dict +different_parameter_values_dict = different_parameter_values_instance.to_dict() +# create an instance of DifferentParameterValues from a dict +different_parameter_values_form_dict = different_parameter_values.from_dict(different_parameter_values_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/python-restclient/docs/ExportFormat.md b/python-restclient/docs/ExportFormat.md new file mode 100644 index 0000000000..70aaec6b71 --- /dev/null +++ b/python-restclient/docs/ExportFormat.md @@ -0,0 +1,10 @@ +# ExportFormat + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/python-restclient/docs/ExportHistory.md b/python-restclient/docs/ExportHistory.md new file mode 100644 index 0000000000..c44a1c621c --- /dev/null +++ b/python-restclient/docs/ExportHistory.md @@ -0,0 +1,46 @@ +# ExportHistory + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**job_id** | **int** | | [optional] +**simulation_ref** | **str** | | [optional] +**export_format** | [**ExportFormat**](ExportFormat.md) | | [optional] +**export_date** | **str** | | [optional] +**uri** | **str** | | [optional] +**data_id_value** | **str** | | [optional] +**sim_name** | **str** | | [optional] +**app_name** | **str** | | [optional] +**bio_name** | **str** | | [optional] +**variables** | **List[str]** | | [optional] +**parameter_values** | [**List[DifferentParameterValues]**](DifferentParameterValues.md) | | [optional] +**start_time_value** | **float** | | [optional] +**end_time_value** | **float** | | [optional] +**saved_file_name_value** | **str** | | [optional] +**application_type_value** | **str** | | [optional] +**non_spatial_value** | **bool** | | [optional] +**z_slices_value** | **int** | | [optional] +**t_slices_value** | **int** | | [optional] +**num_variables_value** | **int** | | [optional] + +## Example + +```python +from vcell_client.models.export_history import ExportHistory + +# TODO update the JSON string below +json = "{}" +# create an instance of ExportHistory from a JSON string +export_history_instance = ExportHistory.from_json(json) +# print the JSON string representation of the object +print ExportHistory.to_json() + +# convert the object into a dict +export_history_dict = export_history_instance.to_dict() +# create an instance of ExportHistory from a dict +export_history_form_dict = export_history.from_dict(export_history_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/python-restclient/docs/ExportResourceApi.md b/python-restclient/docs/ExportResourceApi.md index 0f8f17bfa0..54dd5b77e2 100644 --- a/python-restclient/docs/ExportResourceApi.md +++ b/python-restclient/docs/ExportResourceApi.md @@ -6,6 +6,7 @@ Method | HTTP request | Description ------------- | ------------- | ------------- [**export_n5**](ExportResourceApi.md#export_n5) | **POST** /api/v1/export/N5 | [**export_status**](ExportResourceApi.md#export_status) | **GET** /api/v1/export/status | +[**get_export_history**](ExportResourceApi.md#get_export_history) | **GET** /api/v1/export/history | # **export_n5** @@ -156,3 +157,70 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **get_export_history** +> List[ExportHistory] get_export_history() + + + +### Example + +```python +import time +import os +import vcell_client +from vcell_client.models.export_history import ExportHistory +from vcell_client.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://vcell.cam.uchc.edu +# See configuration.py for a list of all supported configuration parameters. +configuration = vcell_client.Configuration( + host = "https://vcell.cam.uchc.edu" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Enter a context with an instance of the API client +with vcell_client.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = vcell_client.ExportResourceApi(api_client) + + try: + api_response = api_instance.get_export_history() + print("The response of ExportResourceApi->get_export_history:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling ExportResourceApi->get_export_history: %s\n" % e) +``` + + + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**List[ExportHistory]**](ExportHistory.md) + +### Authorization + +[openId](../README.md#openId) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | OK | - | +**401** | Not Authenticated | - | +**403** | Not Allowed | - | +**500** | Data Access Exception | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/python-restclient/docs/HumanReadableExportData.md b/python-restclient/docs/HumanReadableExportData.md index bbe8bee352..c04ba6e6b4 100644 --- a/python-restclient/docs/HumanReadableExportData.md +++ b/python-restclient/docs/HumanReadableExportData.md @@ -7,7 +7,7 @@ Name | Type | Description | Notes **simulation_name** | **str** | | [optional] **biomodel_name** | **str** | | [optional] **application_name** | **str** | | [optional] -**different_parameter_values** | **List[str]** | | [optional] +**different_parameter_values** | [**List[DifferentParameterValues]**](DifferentParameterValues.md) | | [optional] **application_type** | **str** | | [optional] **server_saved_file_name** | **str** | | [optional] **non_spatial** | **bool** | | [optional] diff --git a/python-restclient/test/test_different_parameter_values.py b/python-restclient/test/test_different_parameter_values.py new file mode 100644 index 0000000000..03f9abf69b --- /dev/null +++ b/python-restclient/test/test_different_parameter_values.py @@ -0,0 +1,55 @@ +# coding: utf-8 + +""" + VCell API + + VCell API + + The version of the OpenAPI document: 1.0.1 + Contact: vcell_support@uchc.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest +import datetime + +from vcell_client.models.different_parameter_values import DifferentParameterValues + +class TestDifferentParameterValues(unittest.TestCase): + """DifferentParameterValues unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> DifferentParameterValues: + """Test DifferentParameterValues + include_option is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `DifferentParameterValues` + """ + model = DifferentParameterValues() + if include_optional: + return DifferentParameterValues( + parameter_name = '', + original_value = '', + changed_value = '' + ) + else: + return DifferentParameterValues( + ) + """ + + def testDifferentParameterValues(self): + """Test DifferentParameterValues""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/python-restclient/test/test_export_format.py b/python-restclient/test/test_export_format.py new file mode 100644 index 0000000000..473e94d801 --- /dev/null +++ b/python-restclient/test/test_export_format.py @@ -0,0 +1,35 @@ +# coding: utf-8 + +""" + VCell API + + VCell API + + The version of the OpenAPI document: 1.0.1 + Contact: vcell_support@uchc.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest +import datetime + +from vcell_client.models.export_format import ExportFormat + +class TestExportFormat(unittest.TestCase): + """ExportFormat unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testExportFormat(self): + """Test ExportFormat""" + # inst = ExportFormat() + +if __name__ == '__main__': + unittest.main() diff --git a/python-restclient/test/test_export_history.py b/python-restclient/test/test_export_history.py new file mode 100644 index 0000000000..fb979122d6 --- /dev/null +++ b/python-restclient/test/test_export_history.py @@ -0,0 +1,78 @@ +# coding: utf-8 + +""" + VCell API + + VCell API + + The version of the OpenAPI document: 1.0.1 + Contact: vcell_support@uchc.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest +import datetime + +from vcell_client.models.export_history import ExportHistory + +class TestExportHistory(unittest.TestCase): + """ExportHistory unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ExportHistory: + """Test ExportHistory + include_option is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ExportHistory` + """ + model = ExportHistory() + if include_optional: + return ExportHistory( + job_id = 56, + simulation_ref = '', + export_format = 'CSV', + export_date = '', + uri = '', + data_id_value = '', + sim_name = '', + app_name = '', + bio_name = '', + variables = [ + '' + ], + parameter_values = [ + vcell_client.models.different_parameter_values.DifferentParameterValues( + parameter_name = '', + original_value = '', + changed_value = '', ) + ], + start_time_value = 1.337, + end_time_value = 1.337, + saved_file_name_value = '', + application_type_value = '', + non_spatial_value = True, + z_slices_value = 56, + t_slices_value = 56, + num_variables_value = 56 + ) + else: + return ExportHistory( + ) + """ + + def testExportHistory(self): + """Test ExportHistory""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/python-restclient/vcell_client/__init__.py b/python-restclient/vcell_client/__init__.py index 8ad5416366..7ccbfe809f 100644 --- a/python-restclient/vcell_client/__init__.py +++ b/python-restclient/vcell_client/__init__.py @@ -59,8 +59,11 @@ from vcell_client.models.curve_selection_info import CurveSelectionInfo from vcell_client.models.data_identifier import DataIdentifier from vcell_client.models.detailed_state import DetailedState +from vcell_client.models.different_parameter_values import DifferentParameterValues from vcell_client.models.domain import Domain from vcell_client.models.export_event import ExportEvent +from vcell_client.models.export_format import ExportFormat +from vcell_client.models.export_history import ExportHistory from vcell_client.models.export_progress_type import ExportProgressType from vcell_client.models.exportable_data_type import ExportableDataType from vcell_client.models.extent import Extent diff --git a/python-restclient/vcell_client/api/export_resource_api.py b/python-restclient/vcell_client/api/export_resource_api.py index 51b2e44c4f..674f624751 100644 --- a/python-restclient/vcell_client/api/export_resource_api.py +++ b/python-restclient/vcell_client/api/export_resource_api.py @@ -29,6 +29,7 @@ from typing import List, Optional from vcell_client.models.export_event import ExportEvent +from vcell_client.models.export_history import ExportHistory from vcell_client.models.n5_export_request import N5ExportRequest from vcell_client.api_client import ApiClient @@ -610,3 +611,256 @@ def _export_status_serialize( ) + + + @validate_call + def get_export_history( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> List[ExportHistory]: + """get_export_history + + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_export_history_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[ExportHistory]", + '401': "VCellHTTPError", + '403': None, + '500': "VCellHTTPError" + + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_export_history_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[List[ExportHistory]]: + """get_export_history + + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_export_history_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[ExportHistory]", + '401': "VCellHTTPError", + '403': None, + '500': "VCellHTTPError" + + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_export_history_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """get_export_history + + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_export_history_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[ExportHistory]", + '401': "VCellHTTPError", + '403': None, + '500': "VCellHTTPError" + + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_export_history_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> Tuple: + + _host = None + + _collection_formats: Dict[str, str] = { + + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, str] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'openId' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/export/history', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/python-restclient/vcell_client/models/__init__.py b/python-restclient/vcell_client/models/__init__.py index 5690747f2e..f529412d99 100644 --- a/python-restclient/vcell_client/models/__init__.py +++ b/python-restclient/vcell_client/models/__init__.py @@ -28,8 +28,11 @@ from vcell_client.models.curve_selection_info import CurveSelectionInfo from vcell_client.models.data_identifier import DataIdentifier from vcell_client.models.detailed_state import DetailedState +from vcell_client.models.different_parameter_values import DifferentParameterValues from vcell_client.models.domain import Domain from vcell_client.models.export_event import ExportEvent +from vcell_client.models.export_format import ExportFormat +from vcell_client.models.export_history import ExportHistory from vcell_client.models.export_progress_type import ExportProgressType from vcell_client.models.exportable_data_type import ExportableDataType from vcell_client.models.extent import Extent diff --git a/python-restclient/vcell_client/models/different_parameter_values.py b/python-restclient/vcell_client/models/different_parameter_values.py new file mode 100644 index 0000000000..8851f45eb2 --- /dev/null +++ b/python-restclient/vcell_client/models/different_parameter_values.py @@ -0,0 +1,98 @@ +# coding: utf-8 + +""" + VCell API + + VCell API + + The version of the OpenAPI document: 1.0.1 + Contact: vcell_support@uchc.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import Any, ClassVar, Dict, List, Optional +from pydantic import BaseModel, StrictStr +from pydantic import Field +try: + from typing import Self +except ImportError: + from typing_extensions import Self + +class DifferentParameterValues(BaseModel): + """ + DifferentParameterValues + """ # noqa: E501 + parameter_name: Optional[StrictStr] = Field(default=None, alias="parameterName") + original_value: Optional[StrictStr] = Field(default=None, alias="originalValue") + changed_value: Optional[StrictStr] = Field(default=None, alias="changedValue") + __properties: ClassVar[List[str]] = ["parameterName", "originalValue", "changedValue"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of DifferentParameterValues from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + _dict = self.model_dump( + by_alias=True, + exclude={ + }, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Dict) -> Self: + """Create an instance of DifferentParameterValues from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + # raise errors for additional fields in the input + for _key in obj.keys(): + if _key not in cls.__properties: + raise ValueError("Error due to additional fields (not defined in DifferentParameterValues) in the input: " + _key) + + _obj = cls.model_validate({ + "parameterName": obj.get("parameterName"), + "originalValue": obj.get("originalValue"), + "changedValue": obj.get("changedValue") + }) + return _obj + + diff --git a/python-restclient/vcell_client/models/export_format.py b/python-restclient/vcell_client/models/export_format.py new file mode 100644 index 0000000000..dc6f9728bb --- /dev/null +++ b/python-restclient/vcell_client/models/export_format.py @@ -0,0 +1,56 @@ +# coding: utf-8 + +""" + VCell API + + VCell API + + The version of the OpenAPI document: 1.0.1 + Contact: vcell_support@uchc.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import json +import pprint +import re # noqa: F401 +from enum import Enum + + + +try: + from typing import Self +except ImportError: + from typing_extensions import Self + + +class ExportFormat(str, Enum): + """ + ExportFormat + """ + + """ + allowed enum values + """ + CSV = 'CSV' + HDF5 = 'HDF5' + QUICKTIME = 'QUICKTIME' + GIF = 'GIF' + ANIMATED_GIF = 'ANIMATED_GIF' + FORMAT_JPEG = 'FORMAT_JPEG' + NRRD = 'NRRD' + UCD = 'UCD' + VTK_UNSTRUCT = 'VTK_UNSTRUCT' + VTK_IMAGE = 'VTK_IMAGE' + PLY = 'PLY' + N5 = 'N5' + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of ExportFormat from a JSON string""" + return cls(json.loads(json_str)) + + diff --git a/python-restclient/vcell_client/models/export_history.py b/python-restclient/vcell_client/models/export_history.py new file mode 100644 index 0000000000..a0bbff38da --- /dev/null +++ b/python-restclient/vcell_client/models/export_history.py @@ -0,0 +1,139 @@ +# coding: utf-8 + +""" + VCell API + + VCell API + + The version of the OpenAPI document: 1.0.1 + Contact: vcell_support@uchc.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import Any, ClassVar, Dict, List, Optional, Union +from pydantic import BaseModel, StrictBool, StrictFloat, StrictInt, StrictStr +from pydantic import Field +from vcell_client.models.different_parameter_values import DifferentParameterValues +from vcell_client.models.export_format import ExportFormat +try: + from typing import Self +except ImportError: + from typing_extensions import Self + +class ExportHistory(BaseModel): + """ + ExportHistory + """ # noqa: E501 + job_id: Optional[StrictInt] = Field(default=None, alias="jobID") + simulation_ref: Optional[StrictStr] = Field(default=None, alias="simulationRef") + export_format: Optional[ExportFormat] = Field(default=None, alias="exportFormat") + export_date: Optional[StrictStr] = Field(default=None, alias="exportDate") + uri: Optional[StrictStr] = None + data_id_value: Optional[StrictStr] = Field(default=None, alias="dataIdValue") + sim_name: Optional[StrictStr] = Field(default=None, alias="simName") + app_name: Optional[StrictStr] = Field(default=None, alias="appName") + bio_name: Optional[StrictStr] = Field(default=None, alias="bioName") + variables: Optional[List[StrictStr]] = None + parameter_values: Optional[List[DifferentParameterValues]] = Field(default=None, alias="parameterValues") + start_time_value: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="startTimeValue") + end_time_value: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="endTimeValue") + saved_file_name_value: Optional[StrictStr] = Field(default=None, alias="savedFileNameValue") + application_type_value: Optional[StrictStr] = Field(default=None, alias="applicationTypeValue") + non_spatial_value: Optional[StrictBool] = Field(default=None, alias="nonSpatialValue") + z_slices_value: Optional[StrictInt] = Field(default=None, alias="zSlicesValue") + t_slices_value: Optional[StrictInt] = Field(default=None, alias="tSlicesValue") + num_variables_value: Optional[StrictInt] = Field(default=None, alias="numVariablesValue") + __properties: ClassVar[List[str]] = ["jobID", "simulationRef", "exportFormat", "exportDate", "uri", "dataIdValue", "simName", "appName", "bioName", "variables", "parameterValues", "startTimeValue", "endTimeValue", "savedFileNameValue", "applicationTypeValue", "nonSpatialValue", "zSlicesValue", "tSlicesValue", "numVariablesValue"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of ExportHistory from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + _dict = self.model_dump( + by_alias=True, + exclude={ + }, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in parameter_values (list) + _items = [] + if self.parameter_values: + for _item in self.parameter_values: + if _item: + _items.append(_item.to_dict()) + _dict['parameterValues'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Dict) -> Self: + """Create an instance of ExportHistory from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + # raise errors for additional fields in the input + for _key in obj.keys(): + if _key not in cls.__properties: + raise ValueError("Error due to additional fields (not defined in ExportHistory) in the input: " + _key) + + _obj = cls.model_validate({ + "jobID": obj.get("jobID"), + "simulationRef": obj.get("simulationRef"), + "exportFormat": obj.get("exportFormat"), + "exportDate": obj.get("exportDate"), + "uri": obj.get("uri"), + "dataIdValue": obj.get("dataIdValue"), + "simName": obj.get("simName"), + "appName": obj.get("appName"), + "bioName": obj.get("bioName"), + "variables": obj.get("variables"), + "parameterValues": [DifferentParameterValues.from_dict(_item) for _item in obj.get("parameterValues")] if obj.get("parameterValues") is not None else None, + "startTimeValue": obj.get("startTimeValue"), + "endTimeValue": obj.get("endTimeValue"), + "savedFileNameValue": obj.get("savedFileNameValue"), + "applicationTypeValue": obj.get("applicationTypeValue"), + "nonSpatialValue": obj.get("nonSpatialValue"), + "zSlicesValue": obj.get("zSlicesValue"), + "tSlicesValue": obj.get("tSlicesValue"), + "numVariablesValue": obj.get("numVariablesValue") + }) + return _obj + + diff --git a/python-restclient/vcell_client/models/human_readable_export_data.py b/python-restclient/vcell_client/models/human_readable_export_data.py index d8b3b80707..eac6da9c33 100644 --- a/python-restclient/vcell_client/models/human_readable_export_data.py +++ b/python-restclient/vcell_client/models/human_readable_export_data.py @@ -22,6 +22,7 @@ from typing import Any, ClassVar, Dict, List, Optional from pydantic import BaseModel, StrictBool, StrictInt, StrictStr from pydantic import Field +from vcell_client.models.different_parameter_values import DifferentParameterValues try: from typing import Self except ImportError: @@ -34,7 +35,7 @@ class HumanReadableExportData(BaseModel): simulation_name: Optional[StrictStr] = Field(default=None, alias="simulationName") biomodel_name: Optional[StrictStr] = Field(default=None, alias="biomodelName") application_name: Optional[StrictStr] = Field(default=None, alias="applicationName") - different_parameter_values: Optional[List[StrictStr]] = Field(default=None, alias="differentParameterValues") + different_parameter_values: Optional[List[DifferentParameterValues]] = Field(default=None, alias="differentParameterValues") application_type: Optional[StrictStr] = Field(default=None, alias="applicationType") server_saved_file_name: Optional[StrictStr] = Field(default=None, alias="serverSavedFileName") non_spatial: Optional[StrictBool] = Field(default=None, alias="nonSpatial") @@ -80,6 +81,13 @@ def to_dict(self) -> Dict[str, Any]: }, exclude_none=True, ) + # override the default output from pydantic by calling `to_dict()` of each item in different_parameter_values (list) + _items = [] + if self.different_parameter_values: + for _item in self.different_parameter_values: + if _item: + _items.append(_item.to_dict()) + _dict['differentParameterValues'] = _items return _dict @classmethod @@ -100,7 +108,7 @@ def from_dict(cls, obj: Dict) -> Self: "simulationName": obj.get("simulationName"), "biomodelName": obj.get("biomodelName"), "applicationName": obj.get("applicationName"), - "differentParameterValues": obj.get("differentParameterValues"), + "differentParameterValues": [DifferentParameterValues.from_dict(_item) for _item in obj.get("differentParameterValues")] if obj.get("differentParameterValues") is not None else None, "applicationType": obj.get("applicationType"), "serverSavedFileName": obj.get("serverSavedFileName"), "nonSpatial": obj.get("nonSpatial"), diff --git a/tools/openapi.yaml b/tools/openapi.yaml index 0c7df40f21..1a6233252d 100644 --- a/tools/openapi.yaml +++ b/tools/openapi.yaml @@ -461,6 +461,37 @@ paths: security: - openId: - user + /api/v1/export/history: + get: + tags: + - Export Resource + operationId: getExportHistory + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/ExportHistory' + "401": + description: Not Authenticated + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + "403": + description: Not Allowed + "500": + description: Data Access Exception + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + security: + - openId: + - user /api/v1/export/status: get: tags: @@ -2491,6 +2522,15 @@ components: - WORKEREVENT_FAILURE - JOB_FAILED type: string + DifferentParameterValues: + type: object + properties: + parameterName: + type: string + originalValue: + type: string + changedValue: + type: string Domain: type: object properties: @@ -2519,6 +2559,72 @@ components: type: string humanReadableData: $ref: '#/components/schemas/HumanReadableExportData' + ExportFormat: + enum: + - CSV + - HDF5 + - QUICKTIME + - GIF + - ANIMATED_GIF + - FORMAT_JPEG + - NRRD + - UCD + - VTK_UNSTRUCT + - VTK_IMAGE + - PLY + - N5 + type: string + ExportHistory: + type: object + properties: + jobID: + format: int32 + type: integer + simulationRef: + $ref: '#/components/schemas/KeyValue' + exportFormat: + $ref: '#/components/schemas/ExportFormat' + exportDate: + type: string + uri: + type: string + dataIdValue: + type: string + simName: + type: string + appName: + type: string + bioName: + type: string + variables: + type: array + items: + type: string + parameterValues: + type: array + items: + $ref: '#/components/schemas/DifferentParameterValues' + startTimeValue: + format: double + type: number + endTimeValue: + format: double + type: number + savedFileNameValue: + type: string + applicationTypeValue: + type: string + nonSpatialValue: + type: boolean + zSlicesValue: + format: int32 + type: integer + tSlicesValue: + format: int32 + type: integer + numVariablesValue: + format: int32 + type: integer ExportProgressType: enum: - EXPORT_START @@ -2794,7 +2900,7 @@ components: differentParameterValues: type: array items: - type: string + $ref: '#/components/schemas/DifferentParameterValues' applicationType: type: string serverSavedFileName: diff --git a/vcell-restclient/.openapi-generator/FILES b/vcell-restclient/.openapi-generator/FILES index 602361fc39..6741c43cb0 100644 --- a/vcell-restclient/.openapi-generator/FILES +++ b/vcell-restclient/.openapi-generator/FILES @@ -19,8 +19,11 @@ docs/Curve.md docs/CurveSelectionInfo.md docs/DataIdentifier.md docs/DetailedState.md +docs/DifferentParameterValues.md docs/Domain.md docs/ExportEvent.md +docs/ExportFormat.md +docs/ExportHistory.md docs/ExportProgressType.md docs/ExportResourceApi.md docs/ExportableDataType.md @@ -137,8 +140,11 @@ src/main/java/org/vcell/restclient/model/Curve.java src/main/java/org/vcell/restclient/model/CurveSelectionInfo.java src/main/java/org/vcell/restclient/model/DataIdentifier.java src/main/java/org/vcell/restclient/model/DetailedState.java +src/main/java/org/vcell/restclient/model/DifferentParameterValues.java src/main/java/org/vcell/restclient/model/Domain.java src/main/java/org/vcell/restclient/model/ExportEvent.java +src/main/java/org/vcell/restclient/model/ExportFormat.java +src/main/java/org/vcell/restclient/model/ExportHistory.java src/main/java/org/vcell/restclient/model/ExportProgressType.java src/main/java/org/vcell/restclient/model/ExportableDataType.java src/main/java/org/vcell/restclient/model/Extent.java @@ -206,3 +212,6 @@ src/main/java/org/vcell/restclient/model/VariableSpecs.java src/main/java/org/vcell/restclient/model/VariableType.java src/main/java/org/vcell/restclient/model/Version.java src/main/java/org/vcell/restclient/model/VersionFlag.java +src/test/java/org/vcell/restclient/model/DifferentParameterValuesTest.java +src/test/java/org/vcell/restclient/model/ExportFormatTest.java +src/test/java/org/vcell/restclient/model/ExportHistoryTest.java diff --git a/vcell-restclient/README.md b/vcell-restclient/README.md index d176009a22..33c1deb2b3 100644 --- a/vcell-restclient/README.md +++ b/vcell-restclient/README.md @@ -123,6 +123,8 @@ Class | Method | HTTP request | Description *ExportResourceApi* | [**exportN5WithHttpInfo**](docs/ExportResourceApi.md#exportN5WithHttpInfo) | **POST** /api/v1/export/N5 | *ExportResourceApi* | [**exportStatus**](docs/ExportResourceApi.md#exportStatus) | **GET** /api/v1/export/status | *ExportResourceApi* | [**exportStatusWithHttpInfo**](docs/ExportResourceApi.md#exportStatusWithHttpInfo) | **GET** /api/v1/export/status | +*ExportResourceApi* | [**getExportHistory**](docs/ExportResourceApi.md#getExportHistory) | **GET** /api/v1/export/history | +*ExportResourceApi* | [**getExportHistoryWithHttpInfo**](docs/ExportResourceApi.md#getExportHistoryWithHttpInfo) | **GET** /api/v1/export/history | *FieldDataResourceApi* | [**advancedCreate**](docs/FieldDataResourceApi.md#advancedCreate) | **POST** /api/v1/fieldData/advancedCreate | Create Field Data with granular detail in one request.The following files are accepted: .tif and .zip. *FieldDataResourceApi* | [**advancedCreateWithHttpInfo**](docs/FieldDataResourceApi.md#advancedCreateWithHttpInfo) | **POST** /api/v1/fieldData/advancedCreate | Create Field Data with granular detail in one request.The following files are accepted: .tif and .zip. *FieldDataResourceApi* | [**analyzeFile**](docs/FieldDataResourceApi.md#analyzeFile) | **POST** /api/v1/fieldData/analyzeFile | Analyze uploaded image file (Tiff, Zip, and Non-GPL BioFormats) and return field data. Color mapped images not supported (the colors in those images will be interpreted as separate channels). Filenames must be lowercase alphanumeric, and can contain underscores. @@ -233,8 +235,11 @@ Class | Method | HTTP request | Description - [CurveSelectionInfo](docs/CurveSelectionInfo.md) - [DataIdentifier](docs/DataIdentifier.md) - [DetailedState](docs/DetailedState.md) + - [DifferentParameterValues](docs/DifferentParameterValues.md) - [Domain](docs/Domain.md) - [ExportEvent](docs/ExportEvent.md) + - [ExportFormat](docs/ExportFormat.md) + - [ExportHistory](docs/ExportHistory.md) - [ExportProgressType](docs/ExportProgressType.md) - [ExportableDataType](docs/ExportableDataType.md) - [Extent](docs/Extent.md) diff --git a/vcell-restclient/api/openapi.yaml b/vcell-restclient/api/openapi.yaml index 6216886b8c..1da74fe0cb 100644 --- a/vcell-restclient/api/openapi.yaml +++ b/vcell-restclient/api/openapi.yaml @@ -499,6 +499,38 @@ paths: - Export Resource x-content-type: application/json x-accepts: application/json + /api/v1/export/history: + get: + operationId: getExportHistory + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/ExportHistory' + type: array + description: OK + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + description: Not Authenticated + "403": + description: Not Allowed + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + description: Data Access Exception + security: + - openId: + - user + tags: + - Export Resource + x-accepts: application/json /api/v1/export/status: get: description: Get the status of your export jobs past the timestamp (Unix epoch @@ -2879,6 +2911,19 @@ components: - WORKEREVENT_FAILURE - JOB_FAILED type: string + DifferentParameterValues: + example: + originalValue: originalValue + parameterName: parameterName + changedValue: changedValue + properties: + parameterName: + type: string + originalValue: + type: string + changedValue: + type: string + type: object Domain: example: name: name @@ -2896,8 +2941,12 @@ components: numChannels: 5 applicationType: applicationType differentParameterValues: - - differentParameterValues - - differentParameterValues + - originalValue: originalValue + parameterName: parameterName + changedValue: changedValue + - originalValue: originalValue + parameterName: parameterName + changedValue: changedValue serverSavedFileName: serverSavedFileName subVolume: key: subVolume @@ -2938,6 +2987,100 @@ components: humanReadableData: $ref: '#/components/schemas/HumanReadableExportData' type: object + ExportFormat: + enum: + - CSV + - HDF5 + - QUICKTIME + - GIF + - ANIMATED_GIF + - FORMAT_JPEG + - NRRD + - UCD + - VTK_UNSTRUCT + - VTK_IMAGE + - PLY + - N5 + type: string + ExportHistory: + example: + variables: + - variables + - variables + bioName: bioName + applicationTypeValue: applicationTypeValue + simulationRef: simulationRef + numVariablesValue: 2 + appName: appName + startTimeValue: 6.027456183070403 + endTimeValue: 1.4658129805029452 + uri: uri + jobID: 0 + exportDate: exportDate + savedFileNameValue: savedFileNameValue + nonSpatialValue: true + zSlicesValue: 5 + simName: simName + exportFormat: null + tSlicesValue: 5 + dataIdValue: dataIdValue + parameterValues: + - originalValue: originalValue + parameterName: parameterName + changedValue: changedValue + - originalValue: originalValue + parameterName: parameterName + changedValue: changedValue + properties: + jobID: + format: int32 + type: integer + simulationRef: + type: string + exportFormat: + $ref: '#/components/schemas/ExportFormat' + exportDate: + type: string + uri: + type: string + dataIdValue: + type: string + simName: + type: string + appName: + type: string + bioName: + type: string + variables: + items: + type: string + type: array + parameterValues: + items: + $ref: '#/components/schemas/DifferentParameterValues' + type: array + startTimeValue: + format: double + type: number + endTimeValue: + format: double + type: number + savedFileNameValue: + type: string + applicationTypeValue: + type: string + nonSpatialValue: + type: boolean + zSlicesValue: + format: int32 + type: integer + tSlicesValue: + format: int32 + type: integer + numVariablesValue: + format: int32 + type: integer + type: object ExportProgressType: enum: - EXPORT_START @@ -3501,8 +3644,12 @@ components: numChannels: 5 applicationType: applicationType differentParameterValues: - - differentParameterValues - - differentParameterValues + - originalValue: originalValue + parameterName: parameterName + changedValue: changedValue + - originalValue: originalValue + parameterName: parameterName + changedValue: changedValue serverSavedFileName: serverSavedFileName subVolume: key: subVolume @@ -3521,7 +3668,7 @@ components: type: string differentParameterValues: items: - type: string + $ref: '#/components/schemas/DifferentParameterValues' type: array applicationType: type: string diff --git a/vcell-restclient/docs/DifferentParameterValues.md b/vcell-restclient/docs/DifferentParameterValues.md new file mode 100644 index 0000000000..cc41d6d764 --- /dev/null +++ b/vcell-restclient/docs/DifferentParameterValues.md @@ -0,0 +1,15 @@ + + +# DifferentParameterValues + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**parameterName** | **String** | | [optional] | +|**originalValue** | **String** | | [optional] | +|**changedValue** | **String** | | [optional] | + + + diff --git a/vcell-restclient/docs/ExportFormat.md b/vcell-restclient/docs/ExportFormat.md new file mode 100644 index 0000000000..56f1204e13 --- /dev/null +++ b/vcell-restclient/docs/ExportFormat.md @@ -0,0 +1,33 @@ + + +# ExportFormat + +## Enum + + +* `CSV` (value: `"CSV"`) + +* `HDF5` (value: `"HDF5"`) + +* `QUICKTIME` (value: `"QUICKTIME"`) + +* `GIF` (value: `"GIF"`) + +* `ANIMATED_GIF` (value: `"ANIMATED_GIF"`) + +* `FORMAT_JPEG` (value: `"FORMAT_JPEG"`) + +* `NRRD` (value: `"NRRD"`) + +* `UCD` (value: `"UCD"`) + +* `VTK_UNSTRUCT` (value: `"VTK_UNSTRUCT"`) + +* `VTK_IMAGE` (value: `"VTK_IMAGE"`) + +* `PLY` (value: `"PLY"`) + +* `N5` (value: `"N5"`) + + + diff --git a/vcell-restclient/docs/ExportHistory.md b/vcell-restclient/docs/ExportHistory.md new file mode 100644 index 0000000000..14658914ff --- /dev/null +++ b/vcell-restclient/docs/ExportHistory.md @@ -0,0 +1,31 @@ + + +# ExportHistory + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**jobID** | **Integer** | | [optional] | +|**simulationRef** | **String** | | [optional] | +|**exportFormat** | **ExportFormat** | | [optional] | +|**exportDate** | **String** | | [optional] | +|**uri** | **String** | | [optional] | +|**dataIdValue** | **String** | | [optional] | +|**simName** | **String** | | [optional] | +|**appName** | **String** | | [optional] | +|**bioName** | **String** | | [optional] | +|**variables** | **List<String>** | | [optional] | +|**parameterValues** | [**List<DifferentParameterValues>**](DifferentParameterValues.md) | | [optional] | +|**startTimeValue** | **Double** | | [optional] | +|**endTimeValue** | **Double** | | [optional] | +|**savedFileNameValue** | **String** | | [optional] | +|**applicationTypeValue** | **String** | | [optional] | +|**nonSpatialValue** | **Boolean** | | [optional] | +|**zSlicesValue** | **Integer** | | [optional] | +|**tSlicesValue** | **Integer** | | [optional] | +|**numVariablesValue** | **Integer** | | [optional] | + + + diff --git a/vcell-restclient/docs/ExportResourceApi.md b/vcell-restclient/docs/ExportResourceApi.md index f093dd744a..9e2e3780f2 100644 --- a/vcell-restclient/docs/ExportResourceApi.md +++ b/vcell-restclient/docs/ExportResourceApi.md @@ -8,6 +8,8 @@ All URIs are relative to *https://vcell.cam.uchc.edu* | [**exportN5WithHttpInfo**](ExportResourceApi.md#exportN5WithHttpInfo) | **POST** /api/v1/export/N5 | | | [**exportStatus**](ExportResourceApi.md#exportStatus) | **GET** /api/v1/export/status | | | [**exportStatusWithHttpInfo**](ExportResourceApi.md#exportStatusWithHttpInfo) | **GET** /api/v1/export/status | | +| [**getExportHistory**](ExportResourceApi.md#getExportHistory) | **GET** /api/v1/export/history | | +| [**getExportHistoryWithHttpInfo**](ExportResourceApi.md#getExportHistoryWithHttpInfo) | **GET** /api/v1/export/history | | @@ -302,3 +304,135 @@ ApiResponse<[**List<ExportEvent>**](ExportEvent.md)> | **403** | Not Allowed | - | | **500** | Data Access Exception | - | + +## getExportHistory + +> List getExportHistory() + + + +### Example + +```java +// Import classes: +import org.vcell.restclient.ApiClient; +import org.vcell.restclient.ApiException; +import org.vcell.restclient.Configuration; +import org.vcell.restclient.auth.*; +import org.vcell.restclient.models.*; +import org.vcell.restclient.api.ExportResourceApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://vcell.cam.uchc.edu"); + + + ExportResourceApi apiInstance = new ExportResourceApi(defaultClient); + try { + List result = apiInstance.getExportHistory(); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling ExportResourceApi#getExportHistory"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**List<ExportHistory>**](ExportHistory.md) + + +### Authorization + +[openId](../README.md#openId) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | OK | - | +| **401** | Not Authenticated | - | +| **403** | Not Allowed | - | +| **500** | Data Access Exception | - | + +## getExportHistoryWithHttpInfo + +> ApiResponse> getExportHistory getExportHistoryWithHttpInfo() + + + +### Example + +```java +// Import classes: +import org.vcell.restclient.ApiClient; +import org.vcell.restclient.ApiException; +import org.vcell.restclient.ApiResponse; +import org.vcell.restclient.Configuration; +import org.vcell.restclient.auth.*; +import org.vcell.restclient.models.*; +import org.vcell.restclient.api.ExportResourceApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://vcell.cam.uchc.edu"); + + + ExportResourceApi apiInstance = new ExportResourceApi(defaultClient); + try { + ApiResponse> response = apiInstance.getExportHistoryWithHttpInfo(); + System.out.println("Status code: " + response.getStatusCode()); + System.out.println("Response headers: " + response.getHeaders()); + System.out.println("Response body: " + response.getData()); + } catch (ApiException e) { + System.err.println("Exception when calling ExportResourceApi#getExportHistory"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Response headers: " + e.getResponseHeaders()); + System.err.println("Reason: " + e.getResponseBody()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +ApiResponse<[**List<ExportHistory>**](ExportHistory.md)> + + +### Authorization + +[openId](../README.md#openId) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | OK | - | +| **401** | Not Authenticated | - | +| **403** | Not Allowed | - | +| **500** | Data Access Exception | - | + diff --git a/vcell-restclient/docs/HumanReadableExportData.md b/vcell-restclient/docs/HumanReadableExportData.md index 24b2297849..b2584d2c2f 100644 --- a/vcell-restclient/docs/HumanReadableExportData.md +++ b/vcell-restclient/docs/HumanReadableExportData.md @@ -10,7 +10,7 @@ |**simulationName** | **String** | | [optional] | |**biomodelName** | **String** | | [optional] | |**applicationName** | **String** | | [optional] | -|**differentParameterValues** | **List<String>** | | [optional] | +|**differentParameterValues** | [**List<DifferentParameterValues>**](DifferentParameterValues.md) | | [optional] | |**applicationType** | **String** | | [optional] | |**serverSavedFileName** | **String** | | [optional] | |**nonSpatial** | **Boolean** | | [optional] | diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/api/ExportResourceApi.java b/vcell-restclient/src/main/java/org/vcell/restclient/api/ExportResourceApi.java index 49c8e682c2..efedd7228c 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/api/ExportResourceApi.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/api/ExportResourceApi.java @@ -18,6 +18,7 @@ import org.vcell.restclient.Pair; import org.vcell.restclient.model.ExportEvent; +import org.vcell.restclient.model.ExportHistory; import org.vcell.restclient.model.N5ExportRequest; import org.vcell.restclient.model.VCellHTTPError; @@ -229,6 +230,71 @@ private HttpRequest.Builder exportStatusRequestBuilder(Long timestamp) throws Ap localVarRequestBuilder.header("Accept", "application/json"); + localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * + * + * @return List<ExportHistory> + * @throws ApiException if fails to make API call + */ + public List getExportHistory() throws ApiException { + ApiResponse> localVarResponse = getExportHistoryWithHttpInfo(); + return localVarResponse.getData(); + } + + /** + * + * + * @return ApiResponse<List<ExportHistory>> + * @throws ApiException if fails to make API call + */ + public ApiResponse> getExportHistoryWithHttpInfo() throws ApiException { + HttpRequest.Builder localVarRequestBuilder = getExportHistoryRequestBuilder(); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("getExportHistory", localVarResponse); + } + return new ApiResponse>( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + localVarResponse.body() == null ? null : memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference>() {}) // closes the InputStream + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder getExportHistoryRequestBuilder() throws ApiException { + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/api/v1/export/history"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Accept", "application/json"); + localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); if (memberVarReadTimeout != null) { localVarRequestBuilder.timeout(memberVarReadTimeout); diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/DifferentParameterValues.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/DifferentParameterValues.java new file mode 100644 index 0000000000..52e8f1d9c8 --- /dev/null +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/DifferentParameterValues.java @@ -0,0 +1,222 @@ +/* + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.vcell.restclient.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * DifferentParameterValues + */ +@JsonPropertyOrder({ + DifferentParameterValues.JSON_PROPERTY_PARAMETER_NAME, + DifferentParameterValues.JSON_PROPERTY_ORIGINAL_VALUE, + DifferentParameterValues.JSON_PROPERTY_CHANGED_VALUE +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class DifferentParameterValues { + public static final String JSON_PROPERTY_PARAMETER_NAME = "parameterName"; + private String parameterName; + + public static final String JSON_PROPERTY_ORIGINAL_VALUE = "originalValue"; + private String originalValue; + + public static final String JSON_PROPERTY_CHANGED_VALUE = "changedValue"; + private String changedValue; + + public DifferentParameterValues() { + } + + public DifferentParameterValues parameterName(String parameterName) { + this.parameterName = parameterName; + return this; + } + + /** + * Get parameterName + * @return parameterName + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_PARAMETER_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getParameterName() { + return parameterName; + } + + + @JsonProperty(JSON_PROPERTY_PARAMETER_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setParameterName(String parameterName) { + this.parameterName = parameterName; + } + + + public DifferentParameterValues originalValue(String originalValue) { + this.originalValue = originalValue; + return this; + } + + /** + * Get originalValue + * @return originalValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_ORIGINAL_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getOriginalValue() { + return originalValue; + } + + + @JsonProperty(JSON_PROPERTY_ORIGINAL_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOriginalValue(String originalValue) { + this.originalValue = originalValue; + } + + + public DifferentParameterValues changedValue(String changedValue) { + this.changedValue = changedValue; + return this; + } + + /** + * Get changedValue + * @return changedValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_CHANGED_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getChangedValue() { + return changedValue; + } + + + @JsonProperty(JSON_PROPERTY_CHANGED_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setChangedValue(String changedValue) { + this.changedValue = changedValue; + } + + + /** + * Return true if this DifferentParameterValues object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DifferentParameterValues differentParameterValues = (DifferentParameterValues) o; + return Objects.equals(this.parameterName, differentParameterValues.parameterName) && + Objects.equals(this.originalValue, differentParameterValues.originalValue) && + Objects.equals(this.changedValue, differentParameterValues.changedValue); + } + + @Override + public int hashCode() { + return Objects.hash(parameterName, originalValue, changedValue); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class DifferentParameterValues {\n"); + sb.append(" parameterName: ").append(toIndentedString(parameterName)).append("\n"); + sb.append(" originalValue: ").append(toIndentedString(originalValue)).append("\n"); + sb.append(" changedValue: ").append(toIndentedString(changedValue)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `parameterName` to the URL query string + if (getParameterName() != null) { + joiner.add(String.format("%sparameterName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getParameterName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `originalValue` to the URL query string + if (getOriginalValue() != null) { + joiner.add(String.format("%soriginalValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getOriginalValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `changedValue` to the URL query string + if (getChangedValue() != null) { + joiner.add(String.format("%schangedValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getChangedValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + return joiner.toString(); + } +} + diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportFormat.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportFormat.java new file mode 100644 index 0000000000..e2d6323f6e --- /dev/null +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportFormat.java @@ -0,0 +1,98 @@ +/* + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.vcell.restclient.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Gets or Sets ExportFormat + */ +public enum ExportFormat { + + CSV("CSV"), + + HDF5("HDF5"), + + QUICKTIME("QUICKTIME"), + + GIF("GIF"), + + ANIMATED_GIF("ANIMATED_GIF"), + + FORMAT_JPEG("FORMAT_JPEG"), + + NRRD("NRRD"), + + UCD("UCD"), + + VTK_UNSTRUCT("VTK_UNSTRUCT"), + + VTK_IMAGE("VTK_IMAGE"), + + PLY("PLY"), + + N5("N5"); + + private String value; + + ExportFormat(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ExportFormat fromValue(String value) { + for (ExportFormat b : ExportFormat.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format("%s=%s", prefix, this.toString()); + } + +} + diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java new file mode 100644 index 0000000000..4f923f6727 --- /dev/null +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java @@ -0,0 +1,827 @@ +/* + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.vcell.restclient.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.vcell.restclient.model.DifferentParameterValues; +import org.vcell.restclient.model.ExportFormat; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ExportHistory + */ +@JsonPropertyOrder({ + ExportHistory.JSON_PROPERTY_JOB_I_D, + ExportHistory.JSON_PROPERTY_SIMULATION_REF, + ExportHistory.JSON_PROPERTY_EXPORT_FORMAT, + ExportHistory.JSON_PROPERTY_EXPORT_DATE, + ExportHistory.JSON_PROPERTY_URI, + ExportHistory.JSON_PROPERTY_DATA_ID_VALUE, + ExportHistory.JSON_PROPERTY_SIM_NAME, + ExportHistory.JSON_PROPERTY_APP_NAME, + ExportHistory.JSON_PROPERTY_BIO_NAME, + ExportHistory.JSON_PROPERTY_VARIABLES, + ExportHistory.JSON_PROPERTY_PARAMETER_VALUES, + ExportHistory.JSON_PROPERTY_START_TIME_VALUE, + ExportHistory.JSON_PROPERTY_END_TIME_VALUE, + ExportHistory.JSON_PROPERTY_SAVED_FILE_NAME_VALUE, + ExportHistory.JSON_PROPERTY_APPLICATION_TYPE_VALUE, + ExportHistory.JSON_PROPERTY_NON_SPATIAL_VALUE, + ExportHistory.JSON_PROPERTY_Z_SLICES_VALUE, + ExportHistory.JSON_PROPERTY_T_SLICES_VALUE, + ExportHistory.JSON_PROPERTY_NUM_VARIABLES_VALUE +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ExportHistory { + public static final String JSON_PROPERTY_JOB_I_D = "jobID"; + private Integer jobID; + + public static final String JSON_PROPERTY_SIMULATION_REF = "simulationRef"; + private String simulationRef; + + public static final String JSON_PROPERTY_EXPORT_FORMAT = "exportFormat"; + private ExportFormat exportFormat; + + public static final String JSON_PROPERTY_EXPORT_DATE = "exportDate"; + private String exportDate; + + public static final String JSON_PROPERTY_URI = "uri"; + private String uri; + + public static final String JSON_PROPERTY_DATA_ID_VALUE = "dataIdValue"; + private String dataIdValue; + + public static final String JSON_PROPERTY_SIM_NAME = "simName"; + private String simName; + + public static final String JSON_PROPERTY_APP_NAME = "appName"; + private String appName; + + public static final String JSON_PROPERTY_BIO_NAME = "bioName"; + private String bioName; + + public static final String JSON_PROPERTY_VARIABLES = "variables"; + private List variables; + + public static final String JSON_PROPERTY_PARAMETER_VALUES = "parameterValues"; + private List parameterValues; + + public static final String JSON_PROPERTY_START_TIME_VALUE = "startTimeValue"; + private Double startTimeValue; + + public static final String JSON_PROPERTY_END_TIME_VALUE = "endTimeValue"; + private Double endTimeValue; + + public static final String JSON_PROPERTY_SAVED_FILE_NAME_VALUE = "savedFileNameValue"; + private String savedFileNameValue; + + public static final String JSON_PROPERTY_APPLICATION_TYPE_VALUE = "applicationTypeValue"; + private String applicationTypeValue; + + public static final String JSON_PROPERTY_NON_SPATIAL_VALUE = "nonSpatialValue"; + private Boolean nonSpatialValue; + + public static final String JSON_PROPERTY_Z_SLICES_VALUE = "zSlicesValue"; + private Integer zSlicesValue; + + public static final String JSON_PROPERTY_T_SLICES_VALUE = "tSlicesValue"; + private Integer tSlicesValue; + + public static final String JSON_PROPERTY_NUM_VARIABLES_VALUE = "numVariablesValue"; + private Integer numVariablesValue; + + public ExportHistory() { + } + + public ExportHistory jobID(Integer jobID) { + this.jobID = jobID; + return this; + } + + /** + * Get jobID + * @return jobID + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_JOB_I_D) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getJobID() { + return jobID; + } + + + @JsonProperty(JSON_PROPERTY_JOB_I_D) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setJobID(Integer jobID) { + this.jobID = jobID; + } + + + public ExportHistory simulationRef(String simulationRef) { + this.simulationRef = simulationRef; + return this; + } + + /** + * Get simulationRef + * @return simulationRef + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_SIMULATION_REF) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getSimulationRef() { + return simulationRef; + } + + + @JsonProperty(JSON_PROPERTY_SIMULATION_REF) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSimulationRef(String simulationRef) { + this.simulationRef = simulationRef; + } + + + public ExportHistory exportFormat(ExportFormat exportFormat) { + this.exportFormat = exportFormat; + return this; + } + + /** + * Get exportFormat + * @return exportFormat + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_EXPORT_FORMAT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public ExportFormat getExportFormat() { + return exportFormat; + } + + + @JsonProperty(JSON_PROPERTY_EXPORT_FORMAT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExportFormat(ExportFormat exportFormat) { + this.exportFormat = exportFormat; + } + + + public ExportHistory exportDate(String exportDate) { + this.exportDate = exportDate; + return this; + } + + /** + * Get exportDate + * @return exportDate + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_EXPORT_DATE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getExportDate() { + return exportDate; + } + + + @JsonProperty(JSON_PROPERTY_EXPORT_DATE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExportDate(String exportDate) { + this.exportDate = exportDate; + } + + + public ExportHistory uri(String uri) { + this.uri = uri; + return this; + } + + /** + * Get uri + * @return uri + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_URI) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getUri() { + return uri; + } + + + @JsonProperty(JSON_PROPERTY_URI) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setUri(String uri) { + this.uri = uri; + } + + + public ExportHistory dataIdValue(String dataIdValue) { + this.dataIdValue = dataIdValue; + return this; + } + + /** + * Get dataIdValue + * @return dataIdValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_DATA_ID_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getDataIdValue() { + return dataIdValue; + } + + + @JsonProperty(JSON_PROPERTY_DATA_ID_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDataIdValue(String dataIdValue) { + this.dataIdValue = dataIdValue; + } + + + public ExportHistory simName(String simName) { + this.simName = simName; + return this; + } + + /** + * Get simName + * @return simName + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_SIM_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getSimName() { + return simName; + } + + + @JsonProperty(JSON_PROPERTY_SIM_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSimName(String simName) { + this.simName = simName; + } + + + public ExportHistory appName(String appName) { + this.appName = appName; + return this; + } + + /** + * Get appName + * @return appName + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_APP_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getAppName() { + return appName; + } + + + @JsonProperty(JSON_PROPERTY_APP_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAppName(String appName) { + this.appName = appName; + } + + + public ExportHistory bioName(String bioName) { + this.bioName = bioName; + return this; + } + + /** + * Get bioName + * @return bioName + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_BIO_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getBioName() { + return bioName; + } + + + @JsonProperty(JSON_PROPERTY_BIO_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setBioName(String bioName) { + this.bioName = bioName; + } + + + public ExportHistory variables(List variables) { + this.variables = variables; + return this; + } + + public ExportHistory addVariablesItem(String variablesItem) { + if (this.variables == null) { + this.variables = new ArrayList<>(); + } + this.variables.add(variablesItem); + return this; + } + + /** + * Get variables + * @return variables + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_VARIABLES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getVariables() { + return variables; + } + + + @JsonProperty(JSON_PROPERTY_VARIABLES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setVariables(List variables) { + this.variables = variables; + } + + + public ExportHistory parameterValues(List parameterValues) { + this.parameterValues = parameterValues; + return this; + } + + public ExportHistory addParameterValuesItem(DifferentParameterValues parameterValuesItem) { + if (this.parameterValues == null) { + this.parameterValues = new ArrayList<>(); + } + this.parameterValues.add(parameterValuesItem); + return this; + } + + /** + * Get parameterValues + * @return parameterValues + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_PARAMETER_VALUES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getParameterValues() { + return parameterValues; + } + + + @JsonProperty(JSON_PROPERTY_PARAMETER_VALUES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setParameterValues(List parameterValues) { + this.parameterValues = parameterValues; + } + + + public ExportHistory startTimeValue(Double startTimeValue) { + this.startTimeValue = startTimeValue; + return this; + } + + /** + * Get startTimeValue + * @return startTimeValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_START_TIME_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Double getStartTimeValue() { + return startTimeValue; + } + + + @JsonProperty(JSON_PROPERTY_START_TIME_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setStartTimeValue(Double startTimeValue) { + this.startTimeValue = startTimeValue; + } + + + public ExportHistory endTimeValue(Double endTimeValue) { + this.endTimeValue = endTimeValue; + return this; + } + + /** + * Get endTimeValue + * @return endTimeValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_END_TIME_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Double getEndTimeValue() { + return endTimeValue; + } + + + @JsonProperty(JSON_PROPERTY_END_TIME_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setEndTimeValue(Double endTimeValue) { + this.endTimeValue = endTimeValue; + } + + + public ExportHistory savedFileNameValue(String savedFileNameValue) { + this.savedFileNameValue = savedFileNameValue; + return this; + } + + /** + * Get savedFileNameValue + * @return savedFileNameValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_SAVED_FILE_NAME_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getSavedFileNameValue() { + return savedFileNameValue; + } + + + @JsonProperty(JSON_PROPERTY_SAVED_FILE_NAME_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSavedFileNameValue(String savedFileNameValue) { + this.savedFileNameValue = savedFileNameValue; + } + + + public ExportHistory applicationTypeValue(String applicationTypeValue) { + this.applicationTypeValue = applicationTypeValue; + return this; + } + + /** + * Get applicationTypeValue + * @return applicationTypeValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_APPLICATION_TYPE_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getApplicationTypeValue() { + return applicationTypeValue; + } + + + @JsonProperty(JSON_PROPERTY_APPLICATION_TYPE_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setApplicationTypeValue(String applicationTypeValue) { + this.applicationTypeValue = applicationTypeValue; + } + + + public ExportHistory nonSpatialValue(Boolean nonSpatialValue) { + this.nonSpatialValue = nonSpatialValue; + return this; + } + + /** + * Get nonSpatialValue + * @return nonSpatialValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_NON_SPATIAL_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getNonSpatialValue() { + return nonSpatialValue; + } + + + @JsonProperty(JSON_PROPERTY_NON_SPATIAL_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setNonSpatialValue(Boolean nonSpatialValue) { + this.nonSpatialValue = nonSpatialValue; + } + + + public ExportHistory zSlicesValue(Integer zSlicesValue) { + this.zSlicesValue = zSlicesValue; + return this; + } + + /** + * Get zSlicesValue + * @return zSlicesValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_Z_SLICES_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getzSlicesValue() { + return zSlicesValue; + } + + + @JsonProperty(JSON_PROPERTY_Z_SLICES_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setzSlicesValue(Integer zSlicesValue) { + this.zSlicesValue = zSlicesValue; + } + + + public ExportHistory tSlicesValue(Integer tSlicesValue) { + this.tSlicesValue = tSlicesValue; + return this; + } + + /** + * Get tSlicesValue + * @return tSlicesValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_T_SLICES_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer gettSlicesValue() { + return tSlicesValue; + } + + + @JsonProperty(JSON_PROPERTY_T_SLICES_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void settSlicesValue(Integer tSlicesValue) { + this.tSlicesValue = tSlicesValue; + } + + + public ExportHistory numVariablesValue(Integer numVariablesValue) { + this.numVariablesValue = numVariablesValue; + return this; + } + + /** + * Get numVariablesValue + * @return numVariablesValue + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_NUM_VARIABLES_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getNumVariablesValue() { + return numVariablesValue; + } + + + @JsonProperty(JSON_PROPERTY_NUM_VARIABLES_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setNumVariablesValue(Integer numVariablesValue) { + this.numVariablesValue = numVariablesValue; + } + + + /** + * Return true if this ExportHistory object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ExportHistory exportHistory = (ExportHistory) o; + return Objects.equals(this.jobID, exportHistory.jobID) && + Objects.equals(this.simulationRef, exportHistory.simulationRef) && + Objects.equals(this.exportFormat, exportHistory.exportFormat) && + Objects.equals(this.exportDate, exportHistory.exportDate) && + Objects.equals(this.uri, exportHistory.uri) && + Objects.equals(this.dataIdValue, exportHistory.dataIdValue) && + Objects.equals(this.simName, exportHistory.simName) && + Objects.equals(this.appName, exportHistory.appName) && + Objects.equals(this.bioName, exportHistory.bioName) && + Objects.equals(this.variables, exportHistory.variables) && + Objects.equals(this.parameterValues, exportHistory.parameterValues) && + Objects.equals(this.startTimeValue, exportHistory.startTimeValue) && + Objects.equals(this.endTimeValue, exportHistory.endTimeValue) && + Objects.equals(this.savedFileNameValue, exportHistory.savedFileNameValue) && + Objects.equals(this.applicationTypeValue, exportHistory.applicationTypeValue) && + Objects.equals(this.nonSpatialValue, exportHistory.nonSpatialValue) && + Objects.equals(this.zSlicesValue, exportHistory.zSlicesValue) && + Objects.equals(this.tSlicesValue, exportHistory.tSlicesValue) && + Objects.equals(this.numVariablesValue, exportHistory.numVariablesValue); + } + + @Override + public int hashCode() { + return Objects.hash(jobID, simulationRef, exportFormat, exportDate, uri, dataIdValue, simName, appName, bioName, variables, parameterValues, startTimeValue, endTimeValue, savedFileNameValue, applicationTypeValue, nonSpatialValue, zSlicesValue, tSlicesValue, numVariablesValue); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ExportHistory {\n"); + sb.append(" jobID: ").append(toIndentedString(jobID)).append("\n"); + sb.append(" simulationRef: ").append(toIndentedString(simulationRef)).append("\n"); + sb.append(" exportFormat: ").append(toIndentedString(exportFormat)).append("\n"); + sb.append(" exportDate: ").append(toIndentedString(exportDate)).append("\n"); + sb.append(" uri: ").append(toIndentedString(uri)).append("\n"); + sb.append(" dataIdValue: ").append(toIndentedString(dataIdValue)).append("\n"); + sb.append(" simName: ").append(toIndentedString(simName)).append("\n"); + sb.append(" appName: ").append(toIndentedString(appName)).append("\n"); + sb.append(" bioName: ").append(toIndentedString(bioName)).append("\n"); + sb.append(" variables: ").append(toIndentedString(variables)).append("\n"); + sb.append(" parameterValues: ").append(toIndentedString(parameterValues)).append("\n"); + sb.append(" startTimeValue: ").append(toIndentedString(startTimeValue)).append("\n"); + sb.append(" endTimeValue: ").append(toIndentedString(endTimeValue)).append("\n"); + sb.append(" savedFileNameValue: ").append(toIndentedString(savedFileNameValue)).append("\n"); + sb.append(" applicationTypeValue: ").append(toIndentedString(applicationTypeValue)).append("\n"); + sb.append(" nonSpatialValue: ").append(toIndentedString(nonSpatialValue)).append("\n"); + sb.append(" zSlicesValue: ").append(toIndentedString(zSlicesValue)).append("\n"); + sb.append(" tSlicesValue: ").append(toIndentedString(tSlicesValue)).append("\n"); + sb.append(" numVariablesValue: ").append(toIndentedString(numVariablesValue)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `jobID` to the URL query string + if (getJobID() != null) { + joiner.add(String.format("%sjobID%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getJobID()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `simulationRef` to the URL query string + if (getSimulationRef() != null) { + joiner.add(String.format("%ssimulationRef%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSimulationRef()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `exportFormat` to the URL query string + if (getExportFormat() != null) { + joiner.add(String.format("%sexportFormat%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getExportFormat()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `exportDate` to the URL query string + if (getExportDate() != null) { + joiner.add(String.format("%sexportDate%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getExportDate()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `uri` to the URL query string + if (getUri() != null) { + joiner.add(String.format("%suri%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getUri()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `dataIdValue` to the URL query string + if (getDataIdValue() != null) { + joiner.add(String.format("%sdataIdValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getDataIdValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `simName` to the URL query string + if (getSimName() != null) { + joiner.add(String.format("%ssimName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSimName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `appName` to the URL query string + if (getAppName() != null) { + joiner.add(String.format("%sappName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getAppName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `bioName` to the URL query string + if (getBioName() != null) { + joiner.add(String.format("%sbioName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getBioName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `variables` to the URL query string + if (getVariables() != null) { + for (int i = 0; i < getVariables().size(); i++) { + joiner.add(String.format("%svariables%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix), + URLEncoder.encode(String.valueOf(getVariables().get(i)), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + } + + // add `parameterValues` to the URL query string + if (getParameterValues() != null) { + for (int i = 0; i < getParameterValues().size(); i++) { + if (getParameterValues().get(i) != null) { + joiner.add(getParameterValues().get(i).toUrlQueryString(String.format("%sparameterValues%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `startTimeValue` to the URL query string + if (getStartTimeValue() != null) { + joiner.add(String.format("%sstartTimeValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getStartTimeValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `endTimeValue` to the URL query string + if (getEndTimeValue() != null) { + joiner.add(String.format("%sendTimeValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getEndTimeValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `savedFileNameValue` to the URL query string + if (getSavedFileNameValue() != null) { + joiner.add(String.format("%ssavedFileNameValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSavedFileNameValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `applicationTypeValue` to the URL query string + if (getApplicationTypeValue() != null) { + joiner.add(String.format("%sapplicationTypeValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getApplicationTypeValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `nonSpatialValue` to the URL query string + if (getNonSpatialValue() != null) { + joiner.add(String.format("%snonSpatialValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getNonSpatialValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `zSlicesValue` to the URL query string + if (getzSlicesValue() != null) { + joiner.add(String.format("%szSlicesValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getzSlicesValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `tSlicesValue` to the URL query string + if (gettSlicesValue() != null) { + joiner.add(String.format("%stSlicesValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(gettSlicesValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `numVariablesValue` to the URL query string + if (getNumVariablesValue() != null) { + joiner.add(String.format("%snumVariablesValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getNumVariablesValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + return joiner.toString(); + } +} + diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/HumanReadableExportData.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/HumanReadableExportData.java index 7137081d8e..30eb46ce83 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/HumanReadableExportData.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/HumanReadableExportData.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.vcell.restclient.model.DifferentParameterValues; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @@ -60,7 +61,7 @@ public class HumanReadableExportData { private String applicationName; public static final String JSON_PROPERTY_DIFFERENT_PARAMETER_VALUES = "differentParameterValues"; - private List differentParameterValues; + private List differentParameterValues; public static final String JSON_PROPERTY_APPLICATION_TYPE = "applicationType"; private String applicationType; @@ -161,12 +162,12 @@ public void setApplicationName(String applicationName) { } - public HumanReadableExportData differentParameterValues(List differentParameterValues) { + public HumanReadableExportData differentParameterValues(List differentParameterValues) { this.differentParameterValues = differentParameterValues; return this; } - public HumanReadableExportData addDifferentParameterValuesItem(String differentParameterValuesItem) { + public HumanReadableExportData addDifferentParameterValuesItem(DifferentParameterValues differentParameterValuesItem) { if (this.differentParameterValues == null) { this.differentParameterValues = new ArrayList<>(); } @@ -182,14 +183,14 @@ public HumanReadableExportData addDifferentParameterValuesItem(String differentP @JsonProperty(JSON_PROPERTY_DIFFERENT_PARAMETER_VALUES) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public List getDifferentParameterValues() { + public List getDifferentParameterValues() { return differentParameterValues; } @JsonProperty(JSON_PROPERTY_DIFFERENT_PARAMETER_VALUES) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setDifferentParameterValues(List differentParameterValues) { + public void setDifferentParameterValues(List differentParameterValues) { this.differentParameterValues = differentParameterValues; } @@ -487,9 +488,10 @@ public String toUrlQueryString(String prefix) { // add `differentParameterValues` to the URL query string if (getDifferentParameterValues() != null) { for (int i = 0; i < getDifferentParameterValues().size(); i++) { - joiner.add(String.format("%sdifferentParameterValues%s%s=%s", prefix, suffix, - "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix), - URLEncoder.encode(String.valueOf(getDifferentParameterValues().get(i)), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + if (getDifferentParameterValues().get(i) != null) { + joiner.add(getDifferentParameterValues().get(i).toUrlQueryString(String.format("%sdifferentParameterValues%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix)))); + } } } diff --git a/vcell-restclient/src/test/java/org/vcell/restclient/model/DifferentParameterValuesTest.java b/vcell-restclient/src/test/java/org/vcell/restclient/model/DifferentParameterValuesTest.java new file mode 100644 index 0000000000..b39fe48557 --- /dev/null +++ b/vcell-restclient/src/test/java/org/vcell/restclient/model/DifferentParameterValuesTest.java @@ -0,0 +1,64 @@ +/* + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.vcell.restclient.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Model tests for DifferentParameterValues + */ +public class DifferentParameterValuesTest { + private final DifferentParameterValues model = new DifferentParameterValues(); + + /** + * Model tests for DifferentParameterValues + */ + @Test + public void testDifferentParameterValues() { + // TODO: test DifferentParameterValues + } + + /** + * Test the property 'parameterName' + */ + @Test + public void parameterNameTest() { + // TODO: test parameterName + } + + /** + * Test the property 'originalValue' + */ + @Test + public void originalValueTest() { + // TODO: test originalValue + } + + /** + * Test the property 'changedValue' + */ + @Test + public void changedValueTest() { + // TODO: test changedValue + } + +} diff --git a/vcell-restclient/src/test/java/org/vcell/restclient/model/ExportFormatTest.java b/vcell-restclient/src/test/java/org/vcell/restclient/model/ExportFormatTest.java new file mode 100644 index 0000000000..9e8676431e --- /dev/null +++ b/vcell-restclient/src/test/java/org/vcell/restclient/model/ExportFormatTest.java @@ -0,0 +1,32 @@ +/* + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.vcell.restclient.model; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Model tests for ExportFormat + */ +public class ExportFormatTest { + /** + * Model tests for ExportFormat + */ + @Test + public void testExportFormat() { + // TODO: test ExportFormat + } + +} diff --git a/vcell-restclient/src/test/java/org/vcell/restclient/model/ExportHistoryTest.java b/vcell-restclient/src/test/java/org/vcell/restclient/model/ExportHistoryTest.java new file mode 100644 index 0000000000..316006b7a2 --- /dev/null +++ b/vcell-restclient/src/test/java/org/vcell/restclient/model/ExportHistoryTest.java @@ -0,0 +1,196 @@ +/* + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.vcell.restclient.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.vcell.restclient.model.DifferentParameterValues; +import org.vcell.restclient.model.ExportFormat; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Model tests for ExportHistory + */ +public class ExportHistoryTest { + private final ExportHistory model = new ExportHistory(); + + /** + * Model tests for ExportHistory + */ + @Test + public void testExportHistory() { + // TODO: test ExportHistory + } + + /** + * Test the property 'jobID' + */ + @Test + public void jobIDTest() { + // TODO: test jobID + } + + /** + * Test the property 'simulationRef' + */ + @Test + public void simulationRefTest() { + // TODO: test simulationRef + } + + /** + * Test the property 'exportFormat' + */ + @Test + public void exportFormatTest() { + // TODO: test exportFormat + } + + /** + * Test the property 'exportDate' + */ + @Test + public void exportDateTest() { + // TODO: test exportDate + } + + /** + * Test the property 'uri' + */ + @Test + public void uriTest() { + // TODO: test uri + } + + /** + * Test the property 'dataIdValue' + */ + @Test + public void dataIdValueTest() { + // TODO: test dataIdValue + } + + /** + * Test the property 'simName' + */ + @Test + public void simNameTest() { + // TODO: test simName + } + + /** + * Test the property 'appName' + */ + @Test + public void appNameTest() { + // TODO: test appName + } + + /** + * Test the property 'bioName' + */ + @Test + public void bioNameTest() { + // TODO: test bioName + } + + /** + * Test the property 'variables' + */ + @Test + public void variablesTest() { + // TODO: test variables + } + + /** + * Test the property 'parameterValues' + */ + @Test + public void parameterValuesTest() { + // TODO: test parameterValues + } + + /** + * Test the property 'startTimeValue' + */ + @Test + public void startTimeValueTest() { + // TODO: test startTimeValue + } + + /** + * Test the property 'endTimeValue' + */ + @Test + public void endTimeValueTest() { + // TODO: test endTimeValue + } + + /** + * Test the property 'savedFileNameValue' + */ + @Test + public void savedFileNameValueTest() { + // TODO: test savedFileNameValue + } + + /** + * Test the property 'applicationTypeValue' + */ + @Test + public void applicationTypeValueTest() { + // TODO: test applicationTypeValue + } + + /** + * Test the property 'nonSpatialValue' + */ + @Test + public void nonSpatialValueTest() { + // TODO: test nonSpatialValue + } + + /** + * Test the property 'zSlicesValue' + */ + @Test + public void zSlicesValueTest() { + // TODO: test zSlicesValue + } + + /** + * Test the property 'tSlicesValue' + */ + @Test + public void tSlicesValueTest() { + // TODO: test tSlicesValue + } + + /** + * Test the property 'numVariablesValue' + */ + @Test + public void numVariablesValueTest() { + // TODO: test numVariablesValue + } + +} diff --git a/webapp-ng/src/app/core/modules/openapi/.openapi-generator/FILES b/webapp-ng/src/app/core/modules/openapi/.openapi-generator/FILES index 1787f0845d..200e968142 100644 --- a/webapp-ng/src/app/core/modules/openapi/.openapi-generator/FILES +++ b/webapp-ng/src/app/core/modules/openapi/.openapi-generator/FILES @@ -46,8 +46,11 @@ model/curve-selection-info.ts model/curve.ts model/data-identifier.ts model/detailed-state.ts +model/different-parameter-values.ts model/domain.ts model/export-event.ts +model/export-format.ts +model/export-history.ts model/export-progress-type.ts model/exportable-data-type.ts model/extent.ts diff --git a/webapp-ng/src/app/core/modules/openapi/api/export-resource.service.ts b/webapp-ng/src/app/core/modules/openapi/api/export-resource.service.ts index a911b3fc48..915e6d788a 100644 --- a/webapp-ng/src/app/core/modules/openapi/api/export-resource.service.ts +++ b/webapp-ng/src/app/core/modules/openapi/api/export-resource.service.ts @@ -21,6 +21,8 @@ import { Observable } from 'rxjs'; // @ts-ignore import { ExportEvent } from '../model/export-event'; // @ts-ignore +import { ExportHistory } from '../model/export-history'; +// @ts-ignore import { N5ExportRequest } from '../model/n5-export-request'; // @ts-ignore import { VCellHTTPError } from '../model/v-cell-http-error'; @@ -237,4 +239,63 @@ export class ExportResourceService implements ExportResourceServiceInterface { ); } + /** + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public getExportHistory(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getExportHistory(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>>; + public getExportHistory(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>>; + public getExportHistory(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (openId) required + localVarCredential = this.configuration.lookupCredential('openId'); + if (localVarCredential) { + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/api/v1/export/history`; + return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + } diff --git a/webapp-ng/src/app/core/modules/openapi/api/export-resource.serviceInterface.ts b/webapp-ng/src/app/core/modules/openapi/api/export-resource.serviceInterface.ts index 05c50e07c3..cdb1b10114 100644 --- a/webapp-ng/src/app/core/modules/openapi/api/export-resource.serviceInterface.ts +++ b/webapp-ng/src/app/core/modules/openapi/api/export-resource.serviceInterface.ts @@ -14,6 +14,7 @@ import { HttpHeaders } from '@angular/comm import { Observable } from 'rxjs'; import { ExportEvent } from '../model/models'; +import { ExportHistory } from '../model/models'; import { N5ExportRequest } from '../model/models'; import { VCellHTTPError } from '../model/models'; @@ -40,4 +41,10 @@ export interface ExportResourceServiceInterface { */ exportStatus(timestamp?: number, extraHttpRequestParams?: any): Observable>; + /** + * + * + */ + getExportHistory(extraHttpRequestParams?: any): Observable>; + } diff --git a/webapp-ng/src/app/core/modules/openapi/model/different-parameter-values.ts b/webapp-ng/src/app/core/modules/openapi/model/different-parameter-values.ts new file mode 100644 index 0000000000..d2457537f4 --- /dev/null +++ b/webapp-ng/src/app/core/modules/openapi/model/different-parameter-values.ts @@ -0,0 +1,19 @@ +/** + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export interface DifferentParameterValues { + parameterName?: string; + originalValue?: string; + changedValue?: string; +} + diff --git a/webapp-ng/src/app/core/modules/openapi/model/export-format.ts b/webapp-ng/src/app/core/modules/openapi/model/export-format.ts new file mode 100644 index 0000000000..d63836fc72 --- /dev/null +++ b/webapp-ng/src/app/core/modules/openapi/model/export-format.ts @@ -0,0 +1,30 @@ +/** + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export type ExportFormat = 'CSV' | 'HDF5' | 'QUICKTIME' | 'GIF' | 'ANIMATED_GIF' | 'FORMAT_JPEG' | 'NRRD' | 'UCD' | 'VTK_UNSTRUCT' | 'VTK_IMAGE' | 'PLY' | 'N5'; + +export const ExportFormat = { + Csv: 'CSV' as ExportFormat, + Hdf5: 'HDF5' as ExportFormat, + Quicktime: 'QUICKTIME' as ExportFormat, + Gif: 'GIF' as ExportFormat, + AnimatedGif: 'ANIMATED_GIF' as ExportFormat, + FormatJpeg: 'FORMAT_JPEG' as ExportFormat, + Nrrd: 'NRRD' as ExportFormat, + Ucd: 'UCD' as ExportFormat, + VtkUnstruct: 'VTK_UNSTRUCT' as ExportFormat, + VtkImage: 'VTK_IMAGE' as ExportFormat, + Ply: 'PLY' as ExportFormat, + N5: 'N5' as ExportFormat +}; + diff --git a/webapp-ng/src/app/core/modules/openapi/model/export-history.ts b/webapp-ng/src/app/core/modules/openapi/model/export-history.ts new file mode 100644 index 0000000000..6600d427ef --- /dev/null +++ b/webapp-ng/src/app/core/modules/openapi/model/export-history.ts @@ -0,0 +1,40 @@ +/** + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +import { DifferentParameterValues } from './different-parameter-values'; +import { ExportFormat } from './export-format'; + + +export interface ExportHistory { + jobID?: number; + simulationRef?: string; + exportFormat?: ExportFormat; + exportDate?: string; + uri?: string; + dataIdValue?: string; + simName?: string; + appName?: string; + bioName?: string; + variables?: Array; + parameterValues?: Array; + startTimeValue?: number; + endTimeValue?: number; + savedFileNameValue?: string; + applicationTypeValue?: string; + nonSpatialValue?: boolean; + zSlicesValue?: number; + tSlicesValue?: number; + numVariablesValue?: number; +} +export namespace ExportHistory { +} + + diff --git a/webapp-ng/src/app/core/modules/openapi/model/human-readable-export-data.ts b/webapp-ng/src/app/core/modules/openapi/model/human-readable-export-data.ts index dae9f03882..a4f97b2481 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/human-readable-export-data.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/human-readable-export-data.ts @@ -9,13 +9,14 @@ * https://openapi-generator.tech * Do not edit the class manually. */ +import { DifferentParameterValues } from './different-parameter-values'; export interface HumanReadableExportData { simulationName?: string; biomodelName?: string; applicationName?: string; - differentParameterValues?: Array; + differentParameterValues?: Array; applicationType?: string; serverSavedFileName?: string; nonSpatial?: boolean; diff --git a/webapp-ng/src/app/core/modules/openapi/model/models.ts b/webapp-ng/src/app/core/modules/openapi/model/models.ts index e3cb4a1eef..d4cc51f075 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/models.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/models.ts @@ -14,8 +14,11 @@ export * from './curve'; export * from './curve-selection-info'; export * from './data-identifier'; export * from './detailed-state'; +export * from './different-parameter-values'; export * from './domain'; export * from './export-event'; +export * from './export-format'; +export * from './export-history'; export * from './export-progress-type'; export * from './exportable-data-type'; export * from './extent'; From e59c4765fcb0bfeba9df2ae52cc0610fdb254f1b Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 23 Mar 2026 14:00:38 -0400 Subject: [PATCH 44/65] Insert FRAP Model Into Test DB --- .../org/vcell/restq/TestEndpointUtils.java | 21 +- .../restq/exports/ExportRequestTest.java | 4 +- .../vcell/restq/exports/ExportServerTest.java | 4 +- .../simdata/Administrator/Tutorial_FRAP.vcml | 262 ++++++++++++++++++ 4 files changed, 283 insertions(+), 8 deletions(-) create mode 100644 vcell-rest/src/test/resources/simdata/Administrator/Tutorial_FRAP.vcml diff --git a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java index 1f4e94facf..d40fccd6e6 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -196,6 +196,7 @@ public static void clearAllBioModelEntries(AgroalConnectionFactory agroalConnect connection.prepareStatement("DELETE FROM VC_MATHMODELSIM").execute(); connection.prepareStatement("DELETE FROM VC_SIMCONTEXT").execute(); + connection.prepareStatement("DELETE FROM VC_SIMULATION_EXPORT_HISTORY").execute(); connection.prepareStatement("DELETE FROM VC_SIMULATION").execute(); connection.prepareStatement("DELETE FROM VC_MATHMODELXML").execute(); @@ -215,15 +216,23 @@ public static void clearAllBioModelEntries(AgroalConnectionFactory agroalConnect connection.close(); } - public static void insertAdminsSimulation(DatabaseServerImpl databaseServer, AgroalConnectionFactory connectionFactory) throws IOException, DataAccessException, SQLException { - InputStream xmlFile = TestEndpointUtils.class.getResourceAsStream("/simdata/Administrator/SimID_597714292_0__0.simtask.xml"); + public static void insertAdminsSimulation(DatabaseServerImpl databaseServer, AgroalConnectionFactory connectionFactory) throws IOException, DataAccessException, SQLException, PropertyVetoException, XmlParseException { + InputStream xmlFile = TestEndpointUtils.class.getResourceAsStream("/simdata/Administrator/Tutorial_FRAP.vcml"); assert xmlFile != null; - String readXML = new String(xmlFile.readAllBytes()); - xmlFile.close(); - databaseServer.saveSimulation(administratorUser, new BigString(readXML), false); + BigString bioModelString = new BigString(new String(xmlFile.readAllBytes())); + bioModelString = databaseServer.saveBioModel(administratorUser, bioModelString, new String[]{}); + BioModel bioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelString.toString())); + String simulationKey = bioModel.getSimulation(0).getKey().toString(); + + // Have the key be set, that way the simulation files match the key. Object object = new Object(); Connection connection = connectionFactory.getConnection(object); - connection.prepareStatement("UPDATE vc_simulation SET id = 597714292 WHERE name = 'FRAP'").executeUpdate(); + connection.prepareStatement( + "ALTER TABLE vc_biomodelsim DISABLE TRIGGER ALL; ALTER TABLE vc_simulation DISABLE TRIGGER ALL;" + + "UPDATE vc_biomodelsim SET simref = 597714292 WHERE simref = " + simulationKey + ";" + + "UPDATE vc_simulation SET id = 597714292 WHERE id = " + simulationKey + ";" + + "ALTER TABLE vc_biomodelsim ENABLE TRIGGER ALL; ALTER TABLE vc_simulation ENABLE TRIGGER ALL" + ).executeUpdate(); connection.commit(); connection.close(); } diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java index 19672645b0..e63b8a26ee 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java @@ -9,6 +9,7 @@ import cbit.vcell.solver.AnnotatedFunction; import cbit.vcell.solver.VCSimulationDataIdentifier; import cbit.vcell.solver.VCSimulationIdentifier; +import cbit.vcell.xml.XmlParseException; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.keycloak.client.KeycloakTestClient; import jakarta.inject.Inject; @@ -27,6 +28,7 @@ import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; +import java.beans.PropertyVetoException; import java.io.File; import java.io.IOException; import java.sql.SQLException; @@ -60,7 +62,7 @@ public static void setupConfig(){ } @BeforeEach - public void setUp() throws IOException, DataAccessException, ApiException, SQLException { + public void setUp() throws IOException, DataAccessException, ApiException, SQLException, PropertyVetoException, XmlParseException { aliceAPIClient = TestEndpointUtils.createAuthenticatedAPIClient(keycloakClient, testPort, TestEndpointUtils.TestOIDCUsers.alice); TestEndpointUtils.mapApiClientToAdmin(aliceAPIClient); DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java index bb7f3d9378..d6917a6823 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java @@ -9,6 +9,7 @@ import cbit.vcell.solver.AnnotatedFunction; import cbit.vcell.solver.VCSimulationDataIdentifier; import cbit.vcell.solver.VCSimulationIdentifier; +import cbit.vcell.xml.XmlParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.quarkus.test.junit.QuarkusTest; @@ -30,6 +31,7 @@ import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; +import java.beans.PropertyVetoException; import java.io.File; import java.io.IOException; import java.sql.SQLException; @@ -64,7 +66,7 @@ public static void setupConfig() throws JMSException { } @BeforeEach - public void setUp() throws IOException, DataAccessException, SQLException { + public void setUp() throws IOException, DataAccessException, SQLException, PropertyVetoException, XmlParseException { File testSimData = new File(ExportServerTest.class.getResource("/simdata").getPath()); TestEndpointUtils.setSystemProperties(testSimData.getAbsolutePath(), System.getProperty("java.io.tmpdir")); Cachetable cachetable = new Cachetable(10 * Cachetable.minute, 10000); diff --git a/vcell-rest/src/test/resources/simdata/Administrator/Tutorial_FRAP.vcml b/vcell-rest/src/test/resources/simdata/Administrator/Tutorial_FRAP.vcml new file mode 100644 index 0000000000..4839750961 --- /dev/null +++ b/vcell-rest/src/test/resources/simdata/Administrator/Tutorial_FRAP.vcml @@ -0,0 +1,262 @@ + + + + + cloned from 'Tutorial_FRAP' owned by user tutorial +cloned from 'Tutorial_FRAP' owned by user ACowan +cloned from 'Tutorial_FRAP' owned by user Education +cloned from 'Tutorial_FRAP' owned by user tutorial + + cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user ACowan +cloned from 'FRAP' owned by user Education +cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user susan + + Dextran + + + + + + + + + + + + cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user ACowan +cloned from 'FRAP' owned by user Education +cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user susan + + + + + + cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user ACowan +cloned from 'FRAP' owned by user Education +cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user susan + + cloned from 'FRAP_geometry171328045' owned by user tutorial +cloned from 'FRAP_geometry171328045' owned by user ACowan +cloned from 'FRAP_geometry' owned by user Education +cloned from 'FRAP_geometry' owned by user tutorial +cloned from 'FRAP_geometry' owned by user susan + + + + (((x * x) + (y * y)) < 100.0) + + + 1.0 + + + + + + + + + + + cloned from 'FRAP_geometry171328045' owned by user tutorial +cloned from 'FRAP_geometry171328045' owned by user ACowan +cloned from 'FRAP_geometry' owned by user Education +cloned from 'FRAP_geometry' owned by user tutorial +cloned from 'FRAP_geometry' owned by user susan + + + + + + + + + + + + + + + + (10.0 * ((x < - 5.0) || (x > 5.0) || (y < - 5.0) || (y > 5.0))) + 20.0 + + + + cloned from 'FRAP_130359' owned by user tutorial +cloned from 'FRAP_130359' owned by user ACowan +cloned from 'FRAP_130359' owned by user Education +cloned from 'FRAP_130359' owned by user tutorial +cloned from 'FRAP_130359' owned by user susan + 96485.3321 + 9.64853321E-5 + 1.0E-9 + 6.02214179E11 + 3.141592653589793 + 8314.46261815 + 300.0 + 1.0 + 20.0 + 1000.0 + 0.001660538783162726 + 0.0 + 1.0 + 1.0 + + (10.0 * ((x < - 5.0) || (x > 5.0) || (y < - 5.0) || (y > 5.0))) + (VolumePerUnitVolume_Cyt * vcRegionVolume('Cyt')) + (VolumePerUnitVolume_EC * vcRegionVolume('EC')) + (AreaPerUnitArea_PM * vcRegionArea('Cyt_EC_membrane')) + vcRegionArea('Cyt_EC_membrane') + vcRegionVolume('Cyt') + vcRegionVolume('EC') + + + + + + + + + 0.0 + Dex_diffusionRate + Dex_init_uM + + + + + + + + + + + + + + + + + + + 0.0 + 0.0 + + + + + + cloned from 'FRAP_130359' owned by user tutorial +cloned from 'FRAP_130359' owned by user ACowan +cloned from 'FRAP_130359' owned by user Education +cloned from 'FRAP_130359' owned by user tutorial +cloned from 'FRAP_130359' owned by user susan + + + + cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user ACowan +cloned from 'FRAP 1' owned by user Education +cloned from 'FRAP 1' owned by user tutorial +FRAP Simulation for tutorial. + + + + + + + 2 + + 1 + + + + + + + + + cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user ACowan +cloned from 'FRAP 1' owned by user Education +cloned from 'FRAP 1' owned by user tutorial +FRAP Simulation for tutorial. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user ACowan +cloned from 'FRAP' owned by user Education +cloned from 'FRAP' owned by user tutorial +cloned from 'FRAP' owned by user susan + + + + + + + + + cloned from 'Tutorial_FRAP' owned by user tutorial +cloned from 'Tutorial_FRAP' owned by user ACowan +cloned from 'Tutorial_FRAP' owned by user Education +cloned from 'Tutorial_FRAP' owned by user tutorial + + + + + + + + + + + + cloned from 'Tutorial_FRAP' owned by user tutorial + + + Dextran + + + Cytosol + + + Extracellular + + + + + + From 6a76e1903116628b11d72dc91b9b5e64be64d153 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 23 Mar 2026 14:12:58 -0400 Subject: [PATCH 45/65] Relocate Export History DB Class --- .../vcell/restq/handlers/ExportResource.java | 8 +--- .../vcell/restq/services/ExportService.java | 6 +-- .../restq/services/Exports/ExportService.java | 9 ++--- .../Exports/ServerExportEventController.java | 2 + .../restq/exports/ExportHistoryDBTest.java | 38 +++++++++---------- .../ExportHistoryDBDriver.java | 14 +++---- .../ExportHistoryDBRep.java} | 35 +++++++++++++++-- .../ExportHistoryTable.java | 9 +++-- .../java/cbit/vcell/modeldb/DBTopLevel.java | 1 + 9 files changed, 72 insertions(+), 50 deletions(-) rename vcell-server/src/main/java/cbit/vcell/{modeldb => exports}/ExportHistoryDBDriver.java (89%) rename vcell-server/src/main/java/cbit/vcell/{modeldb/ExportHistoryRep.java => exports/ExportHistoryDBRep.java} (55%) rename vcell-server/src/main/java/cbit/vcell/{modeldb => exports}/ExportHistoryTable.java (96%) diff --git a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java index 6095877f99..615c4a289c 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java +++ b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java @@ -1,11 +1,10 @@ package org.vcell.restq.handlers; -import cbit.vcell.modeldb.ExportHistoryDBDriver; import cbit.rmi.event.ExportEvent; import cbit.vcell.export.server.*; import cbit.vcell.math.Variable; import cbit.vcell.math.VariableType; -import cbit.vcell.modeldb.ExportHistoryRep; +import cbit.vcell.exports.ExportHistoryDBRep; import cbit.vcell.simdata.SpatialSelection; import cbit.vcell.solver.AnnotatedFunction; import com.fasterxml.jackson.core.JsonProcessingException; @@ -30,12 +29,9 @@ import org.vcell.util.document.User; import java.sql.SQLException; -import java.sql.Timestamp; -import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; @Path("/api/v1/export") public class ExportResource { @@ -165,7 +161,7 @@ public record ExportHistory( int tSlicesValue, int numVariablesValue ){ - public static ExportHistory fromExportHistoryRep(ExportHistoryRep rep){ + public static ExportHistory fromExportHistoryRep(ExportHistoryDBRep rep){ return new ExportHistory(rep.jobID(), rep.simulationRef(), rep.exportFormat(), rep.exportDate().toString(), rep.uri(), rep.dataIdValue(), rep.simName(), rep.appName(), rep.bioName(), rep.variables(), rep.parameterValues(), rep.startTimeValue(), rep.endTimeValue(), rep.savedFileNameValue(), rep.applicationTypeValue(), rep.nonSpatialValue(), diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java b/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java index e01f3eecce..429afc2d93 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/ExportService.java @@ -1,7 +1,7 @@ package org.vcell.restq.services; import cbit.vcell.modeldb.DatabaseServerImpl; -import cbit.vcell.modeldb.ExportHistoryRep; +import cbit.vcell.exports.ExportHistoryDBRep; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import org.vcell.restq.db.AgroalConnectionFactory; @@ -18,12 +18,12 @@ public ExportService(AgroalConnectionFactory connectionFactory) throws DataAcces } - public ExportHistoryRep getExportHistory(User user) throws DataAccessException { + public ExportHistoryDBRep getExportHistory(User user) throws DataAccessException { // TODO: Pipe down to DB layer return null; } - public void addExportHistory(User user, ExportHistoryRep history) throws DataAccessException { + public void addExportHistory(User user, ExportHistoryDBRep history) throws DataAccessException { databaseServer.addExportHistory(user, history); } diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java index 5704be33c6..85e2233eba 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java @@ -6,13 +6,12 @@ import cbit.vcell.export.server.FormatSpecificSpecs; import cbit.vcell.export.server.JobRequest; import cbit.vcell.modeldb.DatabaseServerImpl; -import cbit.vcell.modeldb.ExportHistoryRep; +import cbit.vcell.exports.ExportHistoryDBRep; import cbit.vcell.modeldb.SimulationRep; import cbit.vcell.parser.Expression; import cbit.vcell.parser.ExpressionException; import cbit.vcell.solver.AnnotatedFunction; import cbit.vcell.solver.VCSimulationIdentifier; -import com.fasterxml.jackson.databind.ObjectMapper; import io.smallrye.mutiny.Multi; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Instance; @@ -27,11 +26,9 @@ import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; -import java.io.FileNotFoundException; import java.sql.SQLException; import java.time.Instant; import java.util.List; -import java.util.Set; @ApplicationScoped public class ExportService { @@ -50,8 +47,8 @@ public ExportService(AgroalConnectionFactory connectionFactory) throws DataAcces } public List getExportHistory(User user) throws DataAccessException { - List exportHistoryReps = databaseServer.getUsersExportHistory(user); - return exportHistoryReps.stream().map(ExportResource.ExportHistory::fromExportHistoryRep).toList(); + List exportHistoryDBReps = databaseServer.getUsersExportHistory(user); + return exportHistoryDBReps.stream().map(ExportResource.ExportHistory::fromExportHistoryRep).toList(); } public Multi getExportStatuses(User user, long jobID) throws ObjectNotFoundException { diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java index 1a1c8b8712..6db1315e42 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java @@ -5,6 +5,8 @@ import cbit.rmi.event.ExportListener; import cbit.vcell.export.server.ExportEnums; import cbit.vcell.export.server.ExportSpecs; +import cbit.vcell.modeldb.DatabaseServerImpl; +import cbit.vcell.exports.ExportHistoryRep; import cbit.vcell.solver.VCSimulationDataIdentifier; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index b9572a6d8a..8098c6b2ba 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -3,8 +3,8 @@ import cbit.vcell.biomodel.BioModel; import cbit.vcell.export.server.*; import cbit.vcell.modeldb.DatabaseServerImpl; -import cbit.vcell.modeldb.ExportHistoryDBDriver; -import cbit.vcell.modeldb.ExportHistoryRep; +import cbit.vcell.exports.ExportHistoryDBDriver; +import cbit.vcell.exports.ExportHistoryDBRep; import cbit.vcell.resource.PropertyLoader; import cbit.vcell.solver.Simulation; import cbit.vcell.solver.VCSimulationDataIdentifier; @@ -74,7 +74,7 @@ public void createClients() throws ApiException, DataAccessException, PropertyVe simulationKey = savedSimulation.getVersion().getVersionKey(); } - private ExportHistoryRep getExportHistoryRep(int jobID, String uri, Timestamp timestamp){ + private ExportHistoryDBRep getExportHistoryRep(int jobID, String uri, Timestamp timestamp){ VCSimulationIdentifier vcSimId = new VCSimulationIdentifier(simulationKey, TestEndpointUtils.administratorUser); VCDataIdentifier vcdId = new VCSimulationDataIdentifier(vcSimId, jobID); GeometrySpecs geometrySpecs = new GeometrySpecs(null, 1, 1, ExportEnums.GeometryMode.GEOMETRY_FULL); @@ -91,7 +91,7 @@ private ExportHistoryRep getExportHistoryRep(int jobID, String uri, Timestamp ti add(new HumanReadableExportData.DifferentParameterValues("parameter_name2", "original_0", "changed_1")); }}; - return new ExportHistoryRep( + return new ExportHistoryDBRep( jobID, vcSimId.getSimulationKey(), n5Specs.getFormatType(), timestamp, uri, vcdId.getID(), savedSimulation.getName(), "Application Name", savedBioModel.getName(), variableSpecs.getVariableNames(), @@ -119,7 +119,7 @@ public void testAddExportHistory() { try (Connection conn = agroalConnectionFactory.getConnection(null)) { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); - ExportHistoryRep rep = getExportHistoryRep( + ExportHistoryDBRep rep = getExportHistoryRep( 42, "https://vcell.cam.uchc.edu/n5Data/paulricky/5456fb59b530a19.n5?dataSetName=3681309072", now @@ -127,7 +127,7 @@ public void testAddExportHistory() { driver.addExportHistory(conn, user, rep, agroalConnectionFactory.getKeyFactory()); try { - List exportHistoryRecord = driver.getExportHistoryForUser(conn, user); + List exportHistoryRecord = driver.getExportHistoryForUser(conn, user); Assertions.assertEquals(1, exportHistoryRecord.size(), "expected one record"); Assertions.assertTrue(rep.equals(exportHistoryRecord.get(0))); Assertions.assertEquals(rep.parameterValues(), exportHistoryRecord.get(0).parameterValues()); @@ -146,12 +146,12 @@ public void testDeleteExportHistory() throws SQLException { try (Connection conn = agroalConnectionFactory.getConnection(null)) { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); - ExportHistoryRep exportHistoryRep = getExportHistoryRep(7, "to-delete", now); - ExportHistoryRep notDeletedRep = getExportHistoryRep(8, "to-keep", now); + ExportHistoryDBRep exportHistoryDBRep = getExportHistoryRep(7, "to-delete", now); + ExportHistoryDBRep notDeletedRep = getExportHistoryRep(8, "to-keep", now); driver.addExportHistory(conn, user, - exportHistoryRep, + exportHistoryDBRep, agroalConnectionFactory.getKeyFactory() ); driver.addExportHistory(conn, user, @@ -160,12 +160,12 @@ public void testDeleteExportHistory() throws SQLException { ); - List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); Assertions.assertEquals(2, retrievedExportHistory.size(), "expected two records"); - Assertions.assertTrue(exportHistoryRep.equals(retrievedExportHistory.get(0))); + Assertions.assertTrue(exportHistoryDBRep.equals(retrievedExportHistory.get(0))); Assertions.assertTrue(notDeletedRep.equals(retrievedExportHistory.get(1))); - driver.deleteExportHistory(conn, exportHistoryRep.uri()); + driver.deleteExportHistory(conn, exportHistoryDBRep.uri()); retrievedExportHistory = driver.getExportHistoryForUser(conn, user); Assertions.assertEquals(1, retrievedExportHistory.size(), "expected one record after deletion"); Assertions.assertTrue(notDeletedRep.equals(retrievedExportHistory.get(0))); @@ -181,22 +181,22 @@ public void testGetExportHistory() throws SQLException, DataAccessException, Jso try (Connection conn = agroalConnectionFactory.getConnection(null)) { ExportHistoryDBDriver driver = new ExportHistoryDBDriver(null, null); - ExportHistoryRep exportHistoryRep = getExportHistoryRep(100, "uri100", now); - ExportHistoryRep exportHistoryRep1 = getExportHistoryRep(101, "uri101", now); + ExportHistoryDBRep exportHistoryDBRep = getExportHistoryRep(100, "uri100", now); + ExportHistoryDBRep exportHistoryDBRep1 = getExportHistoryRep(101, "uri101", now); driver.addExportHistory(conn, user, - exportHistoryRep, + exportHistoryDBRep, agroalConnectionFactory.getKeyFactory() ); driver.addExportHistory(conn, user, - exportHistoryRep1, + exportHistoryDBRep1, agroalConnectionFactory.getKeyFactory() ); - List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); Assertions.assertEquals(2, retrievedExportHistory.size(), "expected two records"); - Assertions.assertTrue(exportHistoryRep.equals(retrievedExportHistory.get(0))); - Assertions.assertTrue(exportHistoryRep1.equals(retrievedExportHistory.get(1))); + Assertions.assertTrue(exportHistoryDBRep.equals(retrievedExportHistory.get(0))); + Assertions.assertTrue(exportHistoryDBRep1.equals(retrievedExportHistory.get(1))); } } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java similarity index 89% rename from vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java rename to vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java index 932619da08..51f11d97e4 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java @@ -1,6 +1,5 @@ -package cbit.vcell.modeldb; +package cbit.vcell.exports; -import cbit.vcell.export.server.*; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.postgresql.util.PGobject; @@ -13,7 +12,6 @@ import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; -import java.math.BigDecimal; import java.sql.*; import java.util.ArrayList; import java.util.List; @@ -32,7 +30,7 @@ private boolean isOracleConnection(Connection connection) throws SQLException { return productName.contains("oracle"); } - public void addExportHistory(Connection conn, User user, ExportHistoryRep exportHistory, KeyFactory keyFactory) + public void addExportHistory(Connection conn, User user, ExportHistoryDBRep exportHistory, KeyFactory keyFactory) throws SQLException, DependencyException, PermissionException, DataAccessException, ObjectNotFoundException { // 1) insert into vc_model_export_history @@ -99,16 +97,16 @@ public void deleteExportHistory(Connection conn, String uri) throws SQLException } } - public List getExportHistoryForUser(Connection conn, User user) throws SQLException, JsonProcessingException { + public List getExportHistoryForUser(Connection conn, User user) throws SQLException, JsonProcessingException { String sql = "SELECT * FROM vc_simulation_export_history WHERE user_ref = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setLong(1, Long.parseLong(user.getID().toString())); ResultSet resultSet = ps.executeQuery(); - List exportHistoryReps = new ArrayList<>(); + List exportHistoryDBReps = new ArrayList<>(); while (resultSet.next()) { - exportHistoryReps.add(ExportHistoryTable.table.getExportHistoryRecord(resultSet)); + exportHistoryDBReps.add(ExportHistoryTable.table.getExportHistoryRecord(resultSet)); } - return exportHistoryReps; + return exportHistoryDBReps; } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java similarity index 55% rename from vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java rename to vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java index 5cbf4897bf..34e842edb6 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryRep.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java @@ -1,15 +1,16 @@ -package cbit.vcell.modeldb; +package cbit.vcell.exports; import cbit.vcell.export.server.ExportFormat; import cbit.vcell.export.server.ExportSpecs; import cbit.vcell.export.server.HumanReadableExportData; +import cbit.vcell.solver.VCSimulationDataIdentifier; import org.vcell.util.document.KeyValue; -import java.math.BigDecimal; import java.sql.Timestamp; +import java.time.Instant; import java.util.List; -public record ExportHistoryRep( +public record ExportHistoryDBRep( int jobID, KeyValue simulationRef, ExportFormat exportFormat, @@ -30,7 +31,7 @@ public record ExportHistoryRep( int tSlicesValue, int numVariablesValue ) { - public boolean equals(ExportHistoryRep other){ + public boolean equals(ExportHistoryDBRep other){ return this.jobID == other.jobID && this.simulationRef.equals(other.simulationRef) && this.exportFormat.equals(other.exportFormat) && @@ -51,4 +52,30 @@ public boolean equals(ExportHistoryRep other){ this.tSlicesValue == other.tSlicesValue && this.numVariablesValue == other.numVariablesValue; } + + public static ExportHistoryDBRep fromExportSpec(ExportSpecs exportSpecs, String uri, int jobID, VCSimulationDataIdentifier vcSimulationIdentifier){ + double[] times = exportSpecs.getTimeSpecs().getAllTimes(); + Timestamp timestamp = new Timestamp(Instant.now().toEpochMilli()); + return new ExportHistoryDBRep( + jobID, + vcSimulationIdentifier.getSimulationKey(), + exportSpecs.getFormat(), + timestamp, + uri, + vcSimulationIdentifier.getDataKey().toString(), + exportSpecs.getSimulationName(), + exportSpecs.getHumanReadableExportData().applicationName, + exportSpecs.getHumanReadableExportData().biomodelName, + exportSpecs.getVariableSpecs().getVariableNames(), + exportSpecs.getHumanReadableExportData().differentParameterValues, + times[exportSpecs.getTimeSpecs().getBeginTimeIndex()], + times[exportSpecs.getTimeSpecs().getEndTimeIndex()], + exportSpecs.getHumanReadableExportData().serverSavedFileName, + exportSpecs.getHumanReadableExportData().applicationType, + exportSpecs.getHumanReadableExportData().nonSpatial, + exportSpecs.getHumanReadableExportData().zSlices, + exportSpecs.getHumanReadableExportData().tSlices, + exportSpecs.getHumanReadableExportData().numChannels + ); + } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java similarity index 96% rename from vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java rename to vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java index e99b1e18b8..0cebaa0322 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java @@ -1,13 +1,14 @@ -package cbit.vcell.modeldb; +package cbit.vcell.exports; import cbit.sql.Field; import cbit.sql.Table; import cbit.vcell.export.server.ExportFormat; import cbit.vcell.export.server.HumanReadableExportData.DifferentParameterValues; +import cbit.vcell.modeldb.SimulationTable; +import cbit.vcell.modeldb.UserTable; import com.fasterxml.jackson.core.JsonProcessingException; import org.vcell.util.document.KeyValue; -import java.math.BigDecimal; import java.sql.*; import java.util.List; import java.util.StringJoiner; @@ -131,7 +132,7 @@ public void bindForInsert( } - public ExportHistoryRep getExportHistoryRecord(ResultSet rset) throws SQLException, SQLException, JsonProcessingException { + public ExportHistoryDBRep getExportHistoryRecord(ResultSet rset) throws SQLException, SQLException, JsonProcessingException { int simulationRef = rset.getInt(this.simulationRef.getUnqualifiedColName()); @@ -165,7 +166,7 @@ public ExportHistoryRep getExportHistoryRecord(ResultSet rset) throws SQLExcepti - return new ExportHistoryRep( + return new ExportHistoryDBRep( jobId, new KeyValue("" + simulationRef), fmt, date, uriVal, dataIdVal, simNameVal, appNameVal, bioNameVal, variables, parameterValues, startBt, endBt, savedFileVal, appTypeVal, diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index c207e65f7d..e756a04a14 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -15,6 +15,7 @@ import cbit.sql.QueryHashtable; import cbit.sql.RecordChangedException; import cbit.vcell.biomodel.BioModelMetaData; +import cbit.vcell.exports.ExportHistoryDBDriver; import cbit.vcell.field.FieldDataAllDBEntries; import cbit.vcell.field.FieldDataExternalDataIDEntry; import cbit.vcell.field.io.CopyFieldDataResult; From 8f38ed3128e3a039b19d64f24cba2f63a37aeb30 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 31 Mar 2026 11:54:08 -0400 Subject: [PATCH 46/65] Use Key References in Table Remove unneeded information from the table that would over complicate the query and taint the DB with duplicates of information. --- .../src/main/resources/scripts/init.sql | 18 ++- .../restq/exports/ExportHistoryDBTest.java | 70 ++++++----- .../cbit/vcell/exports/ExportHistory.java | 28 +++++ .../vcell/exports/ExportHistoryDBDriver.java | 51 +++----- .../vcell/exports/ExportHistoryDBRep.java | 58 ++------- .../vcell/exports/ExportHistoryTable.java | 114 +++++++++--------- .../java/cbit/vcell/modeldb/DBTopLevel.java | 6 +- .../vcell/modeldb/DatabaseServerImpl.java | 6 +- 8 files changed, 172 insertions(+), 179 deletions(-) create mode 100644 vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index bb70ead9b7..8dc92cc15a 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -82,23 +82,19 @@ CREATE TABLE vc_simulation_export_history ( job_id bigint NOT NULL, user_ref bigint NOT NULL REFERENCES vc_userinfo(id), simulation_ref bigint NOT NULL REFERENCES vc_simulation(id), + biomodel_ref bigint REFERENCES vc_biomodel(id), + mathmodel_ref bigint REFERENCES vc_mathmodel(id), + math_ref bigint NOT NULL REFERENCES vc_math(id), export_format varchar(50) NOT NULL, export_date timestamp NOT NULL, uri text NOT NULL, - data_id varchar(255) NOT NULL, - simulation_name varchar(255) NOT NULL, - application_name varchar(255) NOT NULL, - biomodel_name varchar(255) NOT NULL, variables text[] NOT NULL, - parameter_values jsonb , start_time numeric NOT NULL, end_time numeric NOT NULL, - saved_file_name varchar(255) NOT NULL, - application_type varchar(50) NOT NULL, - non_spatial boolean NOT NULL, - z_slices integer NOT NULL DEFAULT 0, - t_slices integer NOT NULL DEFAULT 0, - num_variables integer NOT NULL DEFAULT 0 + z_slice_start numeric NOT NULL, + z_slice_end numeric NOT NULL, + saved_file_name varchar(50) NOT NULL, + event_status varchar(50) NOT NULL ); diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index 8098c6b2ba..ec5c67adc9 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -2,9 +2,13 @@ import cbit.vcell.biomodel.BioModel; import cbit.vcell.export.server.*; +import cbit.vcell.exports.ExportHistory; +import cbit.vcell.math.Constant; import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.exports.ExportHistoryDBDriver; import cbit.vcell.exports.ExportHistoryDBRep; +import cbit.vcell.parser.Expression; +import cbit.vcell.parser.ExpressionException; import cbit.vcell.resource.PropertyLoader; import cbit.vcell.solver.Simulation; import cbit.vcell.solver.VCSimulationDataIdentifier; @@ -45,36 +49,32 @@ @QuarkusTest public class ExportHistoryDBTest { - @ConfigProperty(name = "quarkus.http.test-port") - Integer testPort; - @Inject AgroalConnectionFactory agroalConnectionFactory; - private ApiClient apiClient; - private User testUser; - - private DatabaseServerImpl databaseServer; private BioModel savedBioModel; private Simulation savedSimulation; private KeyValue simulationKey; @BeforeAll - public static void setupConfig(){ + public static void setupConfig() { PropertyLoader.setConfigProvider(new CDIVCellConfigProvider()); } @BeforeEach - public void createClients() throws ApiException, DataAccessException, PropertyVetoException, XmlParseException, IOException { - databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); + public void initializeDB() throws DataAccessException, PropertyVetoException, XmlParseException, IOException, ExpressionException { + DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); BioModel bioModel = TestEndpointUtils.getTestBioModel(); + bioModel.getSimulation(0).getMathOverrides().putConstant(new Constant("Dex_diffusionRate", new Expression(20))); + bioModel.getSimulation(0).getMathOverrides().putConstant(new Constant("Voltage_PM", new Expression(2))); BigString bioModelXML = databaseServer.saveBioModel(TestEndpointUtils.administratorUser, new BigString(XmlHelper.bioModelToXML(bioModel)), new String[]{}); savedBioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelXML.toString())); + savedSimulation = savedBioModel.getSimulation(0); simulationKey = savedSimulation.getVersion().getVersionKey(); } - private ExportHistoryDBRep getExportHistoryRep(int jobID, String uri, Timestamp timestamp){ + private ExportHistoryDBRep getExportHistoryRep(int jobID, String uri, Timestamp timestamp) { VCSimulationIdentifier vcSimId = new VCSimulationIdentifier(simulationKey, TestEndpointUtils.administratorUser); VCDataIdentifier vcdId = new VCSimulationDataIdentifier(vcSimId, jobID); GeometrySpecs geometrySpecs = new GeometrySpecs(null, 1, 1, ExportEnums.GeometryMode.GEOMETRY_FULL); @@ -86,18 +86,17 @@ private ExportHistoryDBRep getExportHistoryRep(int jobID, String uri, Timestamp N5Specs.CompressionLevel.RAW, "test dataset name"); - List parameterValues = new ArrayList<>(){{ + List parameterValues = new ArrayList<>() {{ add(new HumanReadableExportData.DifferentParameterValues("parameter_name", "original_0", "changed_1")); add(new HumanReadableExportData.DifferentParameterValues("parameter_name2", "original_0", "changed_1")); }}; return new ExportHistoryDBRep( - jobID, vcSimId.getSimulationKey(), n5Specs.getFormatType(), - timestamp, uri, vcdId.getID(), savedSimulation.getName(), - "Application Name", savedBioModel.getName(), variableSpecs.getVariableNames(), - parameterValues, timeSpecs.getAllTimes()[0], timeSpecs.getAllTimes()[1], - "file_on_server", n5Specs.getDataType().name(), false, - 0, 1, 1 + jobID, savedBioModel.getVersion().getVersionKey(), + null, savedSimulation.getKey(), savedSimulation.getMathDescription().getKey(), ExportFormat.N5, + timestamp, uri, variableSpecs.getVariableNames(), + 1.2, 3.4, 1, 1, + "nameOnServer", ExportEnums.ExportProgressType.EXPORT_COMPLETE ); } @@ -127,10 +126,11 @@ public void testAddExportHistory() { driver.addExportHistory(conn, user, rep, agroalConnectionFactory.getKeyFactory()); try { - List exportHistoryRecord = driver.getExportHistoryForUser(conn, user); + List exportHistoryRecord = driver.getExportHistoryForUser(conn, user); Assertions.assertEquals(1, exportHistoryRecord.size(), "expected one record"); - Assertions.assertTrue(rep.equals(exportHistoryRecord.get(0))); - Assertions.assertEquals(rep.parameterValues(), exportHistoryRecord.get(0).parameterValues()); + Assertions.assertTrue(historyDBEqualHistory(rep, exportHistoryRecord.get(0))); + Assertions.assertEquals(savedBioModel.getName(), exportHistoryRecord.get(0).modelName()); + Assertions.assertEquals(savedSimulation.getName(), exportHistoryRecord.get(0).simName()); } catch (SQLException | JsonProcessingException e) { throw new RuntimeException(e); } @@ -160,15 +160,15 @@ public void testDeleteExportHistory() throws SQLException { ); - List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); Assertions.assertEquals(2, retrievedExportHistory.size(), "expected two records"); - Assertions.assertTrue(exportHistoryDBRep.equals(retrievedExportHistory.get(0))); - Assertions.assertTrue(notDeletedRep.equals(retrievedExportHistory.get(1))); + Assertions.assertTrue(historyDBEqualHistory(exportHistoryDBRep, retrievedExportHistory.get(0))); + Assertions.assertTrue(historyDBEqualHistory(notDeletedRep, retrievedExportHistory.get(1))); driver.deleteExportHistory(conn, exportHistoryDBRep.uri()); retrievedExportHistory = driver.getExportHistoryForUser(conn, user); Assertions.assertEquals(1, retrievedExportHistory.size(), "expected one record after deletion"); - Assertions.assertTrue(notDeletedRep.equals(retrievedExportHistory.get(0))); + Assertions.assertTrue(historyDBEqualHistory(notDeletedRep, retrievedExportHistory.get(0))); } catch (DataAccessException | JsonProcessingException e) { throw new RuntimeException(e); } @@ -193,10 +193,24 @@ public void testGetExportHistory() throws SQLException, DataAccessException, Jso agroalConnectionFactory.getKeyFactory() ); - List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); Assertions.assertEquals(2, retrievedExportHistory.size(), "expected two records"); - Assertions.assertTrue(exportHistoryDBRep.equals(retrievedExportHistory.get(0))); - Assertions.assertTrue(exportHistoryDBRep1.equals(retrievedExportHistory.get(1))); + Assertions.assertTrue(historyDBEqualHistory(exportHistoryDBRep, retrievedExportHistory.get(0))); + Assertions.assertTrue(historyDBEqualHistory(exportHistoryDBRep1, retrievedExportHistory.get(1))); } } + + private boolean historyDBEqualHistory(ExportHistoryDBRep dbRep, ExportHistory history) { + return dbRep.simulationRef().equals(history.simulationRef()) && + dbRep.exportFormat().equals(history.exportFormat()) && + dbRep.exportDate().equals(history.exportDate()) && + dbRep.uri().equals(history.uri()) && + List.of(dbRep.variables()).equals(List.of(history.variables())) && + Double.compare(dbRep.startTimeValue(), history.startTimeValue()) == 0 && + Double.compare(dbRep.endTimeValue(), history.endTimeValue()) == 0 && + dbRep.savedFileNameValue().equals(history.savedFileNameValue()) && + dbRep.eventStatus().toString().equals(history.eventStatus().toString()) && + dbRep.zSliceStart() == history.zSliceStart() && + dbRep.zSliceEnd() == history.zSliceEnd(); + } } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java new file mode 100644 index 0000000000..498798179a --- /dev/null +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java @@ -0,0 +1,28 @@ +package cbit.vcell.exports; + +import cbit.vcell.export.server.ExportEnums; +import cbit.vcell.export.server.ExportFormat; +import org.vcell.util.document.KeyValue; + +import java.sql.Timestamp; + +public record ExportHistory( + long exportJobID, + KeyValue simulationRef, + ExportFormat exportFormat, + Timestamp exportDate, + String uri, + String simName, +// String appName, + String modelName, + String[] variables, +// List overrides, + double startTimeValue, + double endTimeValue, + String savedFileNameValue, +// String applicationTypeValue, + int zSliceStart, + int zSliceEnd, + ExportEnums.ExportProgressType eventStatus +) { +} diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java index 51f11d97e4..0038afca1c 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java @@ -37,48 +37,25 @@ public void addExportHistory(Connection conn, User user, ExportHistoryDBRep expo String ehSQL = ExportHistoryTable.table.getInsertSQL(); KeyValue keyValue = keyFactory.getNewKey(conn); - Object jsonDBObjectForParamValues; - try{ - ObjectMapper mapper = new ObjectMapper(); - String jsonVersionOfParamValues = mapper.writeValueAsString(exportHistory.parameterValues()); - if (isOracleConnection(conn)){ - Clob clob = conn.createClob(); - clob.setString(1, jsonVersionOfParamValues); - jsonDBObjectForParamValues = clob; - } else { - PGobject pGobject = new PGobject(); - pGobject.setType("jsonb"); - pGobject.setValue(jsonVersionOfParamValues); - jsonDBObjectForParamValues = pGobject; - } - } catch (JsonProcessingException e){ - throw new DataAccessException(e); - } - - try (PreparedStatement ps = conn.prepareStatement(ehSQL)) { ExportHistoryTable.table.bindForInsert(ps, keyValue, exportHistory.jobID(), Integer.parseInt(user.getID().toString()), + exportHistory.bioModelRef() == null ? null : Integer.parseInt(exportHistory.bioModelRef().toString()), + exportHistory.mathModelRef() == null ? null : Integer.parseInt(exportHistory.mathModelRef().toString()), Integer.parseInt(exportHistory.simulationRef().toString()), + Integer.parseInt(exportHistory.mathRef().toString()), exportHistory.exportFormat(), exportHistory.exportDate(), exportHistory.uri(), - exportHistory.dataIdValue(), - exportHistory.simName(), - exportHistory.appName(), - exportHistory.bioName(), conn.createArrayOf("VARCHAR", exportHistory.variables()), - jsonDBObjectForParamValues, exportHistory.startTimeValue(), exportHistory.endTimeValue(), + exportHistory.zSliceStart(), + exportHistory.zSliceEnd(), exportHistory.savedFileNameValue(), - exportHistory.applicationTypeValue(), - exportHistory.nonSpatialValue(), - exportHistory.zSlicesValue(), - exportHistory.tSlicesValue(), - exportHistory.numVariablesValue() + exportHistory.eventStatus().toString() ); System.out.println("Data insertion tag:"); System.out.println(ps.executeUpdate()); @@ -97,12 +74,22 @@ public void deleteExportHistory(Connection conn, String uri) throws SQLException } } - public List getExportHistoryForUser(Connection conn, User user) throws SQLException, JsonProcessingException { - String sql = "SELECT * FROM vc_simulation_export_history WHERE user_ref = ?"; + // sub selection of sim ref key for that export event, then tie it back to biomodel/sim for getting metadata (name, application, etc) + public List getExportHistoryForUser(Connection conn, User user) throws SQLException, JsonProcessingException, DataAccessException { + String sql = """ + SELECT eh.*, sim.name as sim_name, bio.name as bio_name, bio.childSummaryLRG, bio.childSummarySML, math.name as math_model_name, + sim.mathoverrides, sim.mathOverridesLRG, sim.mathOverridesSML, simContext.name as application_name, simContext.appComponentsLRG, simContext.appComponentsSML + FROM vc_simulation_export_history eh + INNER JOIN vc_simulation sim ON sim.id = eh.simulation_ref + LEFT JOIN vc_biomodel bio ON bio.id = eh.biomodel_ref + LEFT JOIN vc_mathmodel math ON math.id = eh.mathmodel_ref + LEFT JOIN vc_simcontext simContext ON simContext.mathRef = eh.math_ref + WHERE user_ref = ? +"""; PreparedStatement ps = conn.prepareStatement(sql); ps.setLong(1, Long.parseLong(user.getID().toString())); ResultSet resultSet = ps.executeQuery(); - List exportHistoryDBReps = new ArrayList<>(); + List exportHistoryDBReps = new ArrayList<>(); while (resultSet.next()) { exportHistoryDBReps.add(ExportHistoryTable.table.getExportHistoryRecord(resultSet)); } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java index 34e842edb6..5282659db3 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java @@ -1,5 +1,6 @@ package cbit.vcell.exports; +import cbit.vcell.export.server.ExportEnums; import cbit.vcell.export.server.ExportFormat; import cbit.vcell.export.server.ExportSpecs; import cbit.vcell.export.server.HumanReadableExportData; @@ -12,70 +13,35 @@ public record ExportHistoryDBRep( int jobID, + KeyValue bioModelRef, + KeyValue mathModelRef, KeyValue simulationRef, + KeyValue mathRef, ExportFormat exportFormat, Timestamp exportDate, String uri, - String dataIdValue, - String simName, - String appName, - String bioName, String[] variables, - List parameterValues, double startTimeValue, double endTimeValue, + int zSliceStart, + int zSliceEnd, String savedFileNameValue, - String applicationTypeValue, - boolean nonSpatialValue, - int zSlicesValue, - int tSlicesValue, - int numVariablesValue + ExportEnums.ExportProgressType eventStatus ) { public boolean equals(ExportHistoryDBRep other){ return this.jobID == other.jobID && + this.bioModelRef == other.bioModelRef() && + this.mathModelRef() == other.mathModelRef() && this.simulationRef.equals(other.simulationRef) && this.exportFormat.equals(other.exportFormat) && this.exportDate.equals(other.exportDate) && this.uri.equals(other.uri) && - this.dataIdValue.equals(other.dataIdValue) && - this.simName.equals(other.simName) && - this.appName.equals(other.appName) && - this.bioName.equals(other.bioName) && List.of(this.variables).equals(List.of(other.variables)) && - this.parameterValues.equals(other.parameterValues) && Double.compare(this.startTimeValue, other.startTimeValue) == 0 && Double.compare(this.endTimeValue, other.endTimeValue) == 0 && this.savedFileNameValue.equals(other.savedFileNameValue) && - this.applicationTypeValue.equals(other.applicationTypeValue) && - this.nonSpatialValue == other.nonSpatialValue && - this.zSlicesValue == other.zSlicesValue && - this.tSlicesValue == other.tSlicesValue && - this.numVariablesValue == other.numVariablesValue; - } - - public static ExportHistoryDBRep fromExportSpec(ExportSpecs exportSpecs, String uri, int jobID, VCSimulationDataIdentifier vcSimulationIdentifier){ - double[] times = exportSpecs.getTimeSpecs().getAllTimes(); - Timestamp timestamp = new Timestamp(Instant.now().toEpochMilli()); - return new ExportHistoryDBRep( - jobID, - vcSimulationIdentifier.getSimulationKey(), - exportSpecs.getFormat(), - timestamp, - uri, - vcSimulationIdentifier.getDataKey().toString(), - exportSpecs.getSimulationName(), - exportSpecs.getHumanReadableExportData().applicationName, - exportSpecs.getHumanReadableExportData().biomodelName, - exportSpecs.getVariableSpecs().getVariableNames(), - exportSpecs.getHumanReadableExportData().differentParameterValues, - times[exportSpecs.getTimeSpecs().getBeginTimeIndex()], - times[exportSpecs.getTimeSpecs().getEndTimeIndex()], - exportSpecs.getHumanReadableExportData().serverSavedFileName, - exportSpecs.getHumanReadableExportData().applicationType, - exportSpecs.getHumanReadableExportData().nonSpatial, - exportSpecs.getHumanReadableExportData().zSlices, - exportSpecs.getHumanReadableExportData().tSlices, - exportSpecs.getHumanReadableExportData().numChannels - ); + this.eventStatus.equals(other.eventStatus) && + this.zSliceStart == other.zSliceStart && + this.zSliceEnd == other.zSliceEnd; } } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java index 0cebaa0322..e86937636a 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java @@ -2,11 +2,15 @@ import cbit.sql.Field; import cbit.sql.Table; +import cbit.vcell.export.server.ExportEnums; import cbit.vcell.export.server.ExportFormat; -import cbit.vcell.export.server.HumanReadableExportData.DifferentParameterValues; +import cbit.vcell.modeldb.BioModelTable; import cbit.vcell.modeldb.SimulationTable; import cbit.vcell.modeldb.UserTable; -import com.fasterxml.jackson.core.JsonProcessingException; +import cbit.vcell.solver.MathOverrides; +import org.vcell.util.CommentStringTokenizer; +import org.vcell.util.DataAccessException; +import org.vcell.util.document.BioModelChildSummary; import org.vcell.util.document.KeyValue; import java.sql.*; @@ -21,28 +25,24 @@ public class ExportHistoryTable extends Table { public final Field jobId = new Field("job_id", Field.SQLDataType.varchar_50, "NOT NULL"); public final Field userRef = new Field("user_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + UserTable.REF_TYPE); - + public final Field bioModelRef = new Field("biomodel_ref", Field.SQLDataType.integer, "REFERENCES" + BioModelTable.REF_TYPE); + public final Field mathModelRef = new Field("mathmodel_ref", Field.SQLDataType.integer, "REFERENCES" + SimulationTable.REF_TYPE); public final Field simulationRef = new Field("simulation_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + SimulationTable.REF_TYPE); + public final Field mathRef = new Field("math_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + SimulationTable.REF_TYPE); + public final Field exportFormat = new Field("export_format", Field.SQLDataType.varchar_50, "NOT NULL"); public final Field exportDate = new Field("export_date", Field.SQLDataType.date, "NOT NULL"); - public final Field uri = new Field("uri", Field.SQLDataType.varchar2_4000, "NOT NULL"); - public final Field dataId = new Field("data_id", Field.SQLDataType.varchar_255, "NOT NULL"); - public final Field simulationName = new Field("simulation_name", Field.SQLDataType.varchar_255, "NOT NULL"); - public final Field applicationName = new Field("application_name", Field.SQLDataType.varchar_255, "NOT NULL"); - public final Field biomodelName = new Field("biomodel_name", Field.SQLDataType.varchar_255, "NOT NULL"); public final Field variables = new Field("variables", Field.SQLDataType.varchar_255, "[] NOT NULL"); - public final Field changedParameters = new Field("parameter_values", Field.SQLDataType.json, ""); public final Field startTime = new Field("start_time", Field.SQLDataType.number_as_real, "NOT NULL"); public final Field endTime = new Field("end_time", Field.SQLDataType.number_as_real, "NOT NULL"); - public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_255, "NOT NULL"); - public final Field applicationType = new Field("application_type", Field.SQLDataType.varchar_50, "NOT NULL"); - public final Field nonSpatial = new Field("non_spatial", Field.SQLDataType.varchar_50, "NOT NULL"); - public final Field zSlices = new Field("z_slices", Field.SQLDataType.integer, "NOT NULL DEFAULT 0"); - public final Field tSlices = new Field("t_slices", Field.SQLDataType.integer, "NOT NULL DEFAULT 0"); - public final Field numVariables = new Field("num_variables", Field.SQLDataType.integer, "NOT NULL DEFAULT 0"); + public final Field zSliceStart = new Field("z_slice_start", Field.SQLDataType.integer, "NOT NULL"); + public final Field zSliceEnd = new Field("z_slice_end", Field.SQLDataType.integer, "NOT NULL"); + public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_50, "NOT NULL"); + public final Field eventStatus = new Field("event_status", Field.SQLDataType.varchar_50, "NOT NULL"); + //public final Field insertDate = new Field("insert_date", Field.SQLDataType.date, "NOT NULL DEFAULT CURRENT_TIMESTAMP"); @@ -60,10 +60,9 @@ private ExportHistoryTable() { // note that primary key id cannot be placed in fields (will causes class initialization error), Field[] customFields = { // note that primary key id cannot be placed in fields (will causes class initialization error), - jobId, userRef, simulationRef, exportFormat, exportDate, uri, dataId, - simulationName, applicationName, biomodelName, variables, changedParameters, - startTime, endTime, savedFileName, applicationType, nonSpatial, - zSlices, tSlices, numVariables + jobId, userRef, bioModelRef, mathModelRef, simulationRef, mathRef, + exportFormat, exportDate, uri, variables, + startTime, endTime, zSliceStart, zSliceEnd, savedFileName, eventStatus }; addFields(customFields); } @@ -88,54 +87,48 @@ public void bindForInsert( KeyValue keyValue, int jobIdValue, int userRefValue, + Integer bioModelRef, + Integer mathModelRef, int simulationRef, + int mathRef, ExportFormat fmt, Timestamp exportDateValue, String uriValue, - String dataIdValue, - String simName, - String appName, - String bioName, Array variables, - Object parameterValues, double startTimeValue, double endTimeValue, + int zSliceStartValue, + int zSliceEndValue, String savedFileNameValue, - String applicationTypeValue, - boolean nonSpatialValue, - int zSlicesValue, - int tSlicesValue, - int numVariablesValue + String eventStatusValue ) throws SQLException { int i = 1; ps.setInt (i++, Integer.parseInt(keyValue.toString())); ps.setLong (i++, jobIdValue); ps.setLong (i++, userRefValue); + if (bioModelRef != null) {ps.setLong(i++, bioModelRef);} else { + ps.setNull(i++, java.sql.Types.INTEGER); + } + if (mathModelRef != null) {ps.setLong(i++, mathModelRef);} else { + ps.setNull(i++, java.sql.Types.INTEGER); + } ps.setLong (i++, simulationRef); + ps.setLong (i++, mathRef); ps.setString (i++, fmt.name()); ps.setTimestamp (i++, exportDateValue); ps.setString (i++, uriValue); - ps.setString (i++, dataIdValue); - ps.setString (i++, simName); - ps.setString (i++, appName); - ps.setString (i++, bioName); ps.setArray (i++, variables); - ps.setObject (i++, parameterValues); ps.setDouble (i++, startTimeValue); ps.setDouble (i++, endTimeValue); + ps.setInt (i++, zSliceStartValue); + ps.setInt (i++, zSliceEndValue); ps.setString (i++, savedFileNameValue); - ps.setString (i++, applicationTypeValue); - ps.setBoolean (i++, nonSpatialValue); - ps.setInt (i++, zSlicesValue); - ps.setInt (i++, tSlicesValue); - ps.setInt (i++, numVariablesValue); - + ps.setString (i++, eventStatusValue); } - public ExportHistoryDBRep getExportHistoryRecord(ResultSet rset) throws SQLException, SQLException, JsonProcessingException { - - int simulationRef = rset.getInt(this.simulationRef.getUnqualifiedColName()); + public ExportHistory getExportHistoryRecord(ResultSet rset) throws SQLException, SQLException, DataAccessException { + long simulationRef = rset.getLong(this.simulationRef.getUnqualifiedColName()); // enums & timestamps ExportFormat fmt = ExportFormat.valueOf(rset.getString(this.exportFormat.getUnqualifiedColName())); Timestamp date = rset.getTimestamp(this.exportDate.getUnqualifiedColName()); @@ -143,34 +136,39 @@ public ExportHistoryDBRep getExportHistoryRecord(ResultSet rset) throws SQLExcep // strings int jobId = rset.getInt(this.jobId.getUnqualifiedColName()); String uriVal = rset.getString(this.uri.getUnqualifiedColName()); - String dataIdVal = rset.getString(this.dataId.getUnqualifiedColName()); - String simNameVal = rset.getString(this.simulationName.getUnqualifiedColName()); - String appNameVal = rset.getString(this.applicationName.getUnqualifiedColName()); - String bioNameVal = rset.getString(this.biomodelName.getUnqualifiedColName()); + String simNameVal = rset.getString("sim_name"); + String mathModelNameVal = rset.getString("math_model_name"); + String bioNameVal = rset.getString("bio_name"); + String modelName = mathModelNameVal == null ? bioNameVal : mathModelNameVal; - // text array of variables String[] variables = (String[]) rset.getArray(this.variables.getUnqualifiedColName()).getArray(); - List parameterValues = DifferentParameterValues.fromJSON(rset.getString(this.changedParameters.getUnqualifiedColName())); // numeric ranges double startBt = rset.getDouble(this.startTime.getUnqualifiedColName()); double endBt = rset.getDouble(this.endTime.getUnqualifiedColName()); + int zS = rset.getInt(this.zSliceStart.getUnqualifiedColName()); + int zE = rset.getInt(this.zSliceEnd.getUnqualifiedColName()); // more strings & flags String savedFileVal = rset.getString(this.savedFileName.getUnqualifiedColName()); - String appTypeVal = rset.getString(this.applicationType.getUnqualifiedColName()); - boolean nonSp = rset.getBoolean(this.nonSpatial.getUnqualifiedColName()); - int zS = rset.getInt(this.zSlices.getUnqualifiedColName()); - int tS = rset.getInt(this.tSlices.getUnqualifiedColName()); - int numV = rset.getInt(this.numVariables.getUnqualifiedColName()); + String eventStatusVal = rset.getString(this.eventStatus.getUnqualifiedColName()); + + +// String mathOverrides = rset.getString("mathOverrides"); +// mathOverrides = mathOverrides == null ? rset.getString("mathOverridesSML") : mathOverrides; +// mathOverrides = mathOverrides == null ? rset.getString("mathOverridesLRG") : mathOverrides; +// List overrides = MathOverrides.parseOverrideElementsFromVCML(new CommentStringTokenizer(mathOverrides)); +// String childSummary = rset.getString("childSummarySML"); +// childSummary = childSummary == null ? rset.getString("childSummaryLRG") : childSummary; +// BioModelChildSummary bioModelChildSummary = BioModelChildSummary.fromDatabaseSerialization(childSummary); - return new ExportHistoryDBRep( + return new ExportHistory( jobId, new KeyValue("" + simulationRef), fmt, date, - uriVal, dataIdVal, simNameVal, appNameVal, bioNameVal, variables, - parameterValues, startBt, endBt, savedFileVal, appTypeVal, - nonSp, zS, tS, numV + uriVal, simNameVal, modelName, variables, + startBt, endBt, savedFileVal, + zS, zE, ExportEnums.ExportProgressType.valueOf(eventStatusVal) ); } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index e756a04a14..a708d8b946 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -15,7 +15,9 @@ import cbit.sql.QueryHashtable; import cbit.sql.RecordChangedException; import cbit.vcell.biomodel.BioModelMetaData; +import cbit.vcell.exports.ExportHistory; import cbit.vcell.exports.ExportHistoryDBDriver; +import cbit.vcell.exports.ExportHistoryDBRep; import cbit.vcell.field.FieldDataAllDBEntries; import cbit.vcell.field.FieldDataExternalDataIDEntry; import cbit.vcell.field.io.CopyFieldDataResult; @@ -2259,7 +2261,7 @@ public SimulationRep getSimulationRep(KeyValue simKey, boolean bEnableRetry) thr } } - public void insertExportHistory(User user, ExportHistoryRep exportHistoryValues, boolean bEnableRetry) throws SQLException, DataAccessException { + public void insertExportHistory(User user, ExportHistoryDBRep exportHistoryValues, boolean bEnableRetry) throws SQLException, DataAccessException { Object lock = new Object(); Connection con = conFactory.getConnection(lock); try { @@ -2282,7 +2284,7 @@ public void insertExportHistory(User user, ExportHistoryRep exportHistoryValues, } } - public List getUsersExportHistory(User user, boolean bEnableRetry) throws SQLException, DataAccessException { + public List getUsersExportHistory(User user, boolean bEnableRetry) throws SQLException, DataAccessException { Object lock = new Object(); Connection con = conFactory.getConnection(lock); try { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java index 969c723939..1d0aa4fb7a 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java @@ -15,6 +15,8 @@ import cbit.sql.QueryHashtable; import cbit.util.xml.XmlUtil; import cbit.vcell.biomodel.BioModelMetaData; +import cbit.vcell.exports.ExportHistory; +import cbit.vcell.exports.ExportHistoryDBRep; import cbit.vcell.field.FieldDataAllDBEntries; import cbit.vcell.field.FieldDataExternalDataIDEntry; import cbit.vcell.field.io.CopyFieldDataResult; @@ -1355,7 +1357,7 @@ public BigString saveVCImageAs(User user, BigString vcImageXML, java.lang.String } } - public void addExportHistory(User user, ExportHistoryRep exportHistory) throws DataAccessException { + public void addExportHistory(User user, ExportHistoryDBRep exportHistory) throws DataAccessException { try { dbTop.insertExportHistory(user, exportHistory, true); } catch (SQLException e) { @@ -1363,7 +1365,7 @@ public void addExportHistory(User user, ExportHistoryRep exportHistory) throws D } } - public List getUsersExportHistory(User user) throws DataAccessException { + public List getUsersExportHistory(User user) throws DataAccessException { try { return dbTop.getUsersExportHistory(user, true); } catch (SQLException e) { From ae70c0cc6425a323dccbbf59f20d867bfd5dfaec Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 31 Mar 2026 14:22:44 -0400 Subject: [PATCH 47/65] Remove Human Readable Export from Export Spec --- .../vcell/client/data/PDEExportDataPanel.java | 4 +-- .../vcell/export/gui/N5SettingsPanel.java | 2 +- .../server/ClientExportEventController.java | 1 - .../cbit/vcell/export/server/ExportSpecs.java | 27 +------------------ .../cbit/vcell/export/server/N5Exporter.java | 5 +--- .../cbit/vcell/export/server/N5Specs.java | 13 --------- .../cbit/vcell/export/N5ExporterTest.java | 11 ++++---- .../activemq/ExportRequestListenerMQ.java | 6 +---- 8 files changed, 10 insertions(+), 59 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java index e0c7f87e80..e6e1ddffb2 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java @@ -694,7 +694,7 @@ private ExportSpecs getExportSpecs() { throw new IllegalArgumentException("Expected " + SimulationContext.class.getName() + " or " + MathModel.class.getName()); } - ExportSpecs exportSpecs = new ExportSpecs( + return new ExportSpecs( vcDataIdentifier, getExportSettings1().getSelectedFormat(), variableSpecs, @@ -704,8 +704,6 @@ private ExportSpecs getExportSpecs() { dataInfoProvider.getSimulationModelInfo().getSimulationName(), dataInfoProvider.getSimulationModelInfo().getContextName() ); - exportSpecs.setExportMetaData(humanReadableExportData); - return exportSpecs; } private ExportSpecs.SimulationSelector createSimulationSelector(){ diff --git a/vcell-client/src/main/java/cbit/vcell/export/gui/N5SettingsPanel.java b/vcell-client/src/main/java/cbit/vcell/export/gui/N5SettingsPanel.java index 793db5fe8a..332ae06aa7 100644 --- a/vcell-client/src/main/java/cbit/vcell/export/gui/N5SettingsPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/export/gui/N5SettingsPanel.java @@ -264,7 +264,7 @@ public N5Specs getN5Specs(){ int[] paramScanIndexes = simulationSelector == null ? null : simulationSelector.getselectedParamScanIndexes(); String dataSetName = getJTextFieldDataSetName().getText(); - return new N5Specs(ExportEnums.ExportableDataType.PDE_VARIABLE_DATA, ExportFormat.N5, N5Specs.CompressionLevel.GZIP, dataSetName); + return new N5Specs(ExportEnums.ExportableDataType.PDE_VARIABLE_DATA, ExportFormat.N5, dataSetName, null); } private JLabel lblSeeVcellHelp; diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ClientExportEventController.java b/vcell-core/src/main/java/cbit/vcell/export/server/ClientExportEventController.java index 5464079c68..7772efa011 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ClientExportEventController.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ClientExportEventController.java @@ -45,7 +45,6 @@ public ExportEvent fireExportCompleted(long jobID, VCDataIdentifier vcdID, Strin ExportEvent event = new ExportEvent( this, jobID, user, vcdID.getID(), dataKey, ExportEnums.ExportProgressType.EXPORT_COMPLETE, format, location, null); - event.setHumanReadableExportData(exportSpecs != null ? exportSpecs.getHumanReadableExportData() : null); fireExportEvent(event); return event; } diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java index 1adf1ae1d2..91279d127e 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java @@ -39,8 +39,6 @@ public class ExportSpecs implements Serializable { private String simulatioName; private String contextName; - private HumanReadableExportData humanReadableExportData; - public interface SimulationSelector{ public void selectSimulations(); public void selectParamScanInfo(); @@ -50,26 +48,11 @@ public interface SimulationSelector{ public int getNumAvailableParamScans(); } - public ExportSpecs(org.vcell.util.document.VCDataIdentifier vcdID, ExportFormat format, - VariableSpecs variableSpecs, TimeSpecs timeSpecs, - GeometrySpecs geometrySpecs, FormatSpecificSpecs formatSpecificSpecs, - String simulationName,String contextName) { - this.vcDataIdentifier = vcdID; - this.format = format; - this.variableSpecs = variableSpecs; - this.timeSpecs = timeSpecs; - this.geometrySpecs = geometrySpecs; - this.formatSpecificSpecs = formatSpecificSpecs; - this.simulatioName = simulationName; - this.contextName = contextName; - } - @JsonCreator public ExportSpecs(@JsonProperty("vcdataIdentifier") VCDataIdentifier vcdataIdentifier, @JsonProperty("format") ExportFormat format, @JsonProperty("variableSpecs") VariableSpecs variableSpecs, @JsonProperty("timeSpecs") TimeSpecs timeSpecs, @JsonProperty("geometrySpecs") GeometrySpecs geometrySpecs, @JsonProperty("formatSpecificSpecs") FormatSpecificSpecs formatSpecificSpecs, - @JsonProperty("simulationName") String simulationName, @JsonProperty("contextName") String contextName, - @JsonProperty("humanReadableExportData") HumanReadableExportData humanReadableExportData) { + @JsonProperty("simulationName") String simulationName, @JsonProperty("contextName") String contextName) { this.vcDataIdentifier = vcdataIdentifier; this.format = format; this.variableSpecs = variableSpecs; @@ -78,7 +61,6 @@ public ExportSpecs(@JsonProperty("vcdataIdentifier") VCDataIdentifier vcdataIden this.formatSpecificSpecs = formatSpecificSpecs; this.simulatioName = simulationName; this.contextName = contextName; - this.humanReadableExportData = humanReadableExportData; } public String getContextName(){ @@ -205,11 +187,4 @@ public static void setupDisplayAdapterService(DisplayPreferences displayPreferen System.arraycopy(specialColors, 0, displayAdapterService.getSpecialColors(), 0,specialColors.length); } - public void setExportMetaData(HumanReadableExportData humanReadableExportData){ - this.humanReadableExportData = humanReadableExportData; - } - - public HumanReadableExportData getHumanReadableExportData(){ - return humanReadableExportData; - } } diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/N5Exporter.java b/vcell-core/src/main/java/cbit/vcell/export/server/N5Exporter.java index 1fcfd79a47..4578c2f7e4 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/N5Exporter.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/N5Exporter.java @@ -138,7 +138,7 @@ private ExportOutput exportToN5(OutputContext outputContext, long jobID, N5Specs N5Specs.writeImageJMetaData(jobID, dimensions, blockSize, n5Specs.getCompression(), n5FSWriter, n5Specs.dataSetName, numVariables, sizeZ, allTimes.length, - exportSpecs.getHumanReadableExportData().subVolume, + n5Specs.getSubVolumeMapping(), lengthPerPixelY, lengthPerPixelX, lengthPerPixelZ, lengthUnit.getSymbol(), channelInfo); int timeLoops = 1; @@ -181,9 +181,6 @@ private ExportOutput exportToN5(OutputContext outputContext, long jobID, N5Specs timeLoops += 1; } n5FSWriter.close(); - exportSpecs.getHumanReadableExportData().numChannels = (int) dimensions[2]; - exportSpecs.getHumanReadableExportData().zSlices = (int) dimensions[3]; - exportSpecs.getHumanReadableExportData().tSlices = (int) dimensions[4]; ExportOutput exportOutput = new ExportOutput(true, "." + N5Specs.n5Suffix, vcDataID.getID(), getN5FileNameHash(), fileDataContainerManager); return exportOutput; } diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/N5Specs.java b/vcell-core/src/main/java/cbit/vcell/export/server/N5Specs.java index 084963df0b..26c2657ad5 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/N5Specs.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/N5Specs.java @@ -49,19 +49,6 @@ public static enum CompressionLevel{ GZIP } -/** - * TextSpecs constructor comment. - */ - public N5Specs(ExportEnums.ExportableDataType dataType, ExportFormat format, - CompressionLevel compressionLevel, String dataSetName) { - super("N5"); - this.formatType = format; - this.dataType = dataType; - this.compression = compressionLevel; - this.dataSetName = dataSetName; - this.subVolumeMapping = null; // it gets set within the HumanReadableExportData - } - @JsonCreator public N5Specs(@JsonProperty("dataType") ExportEnums.ExportableDataType dataType, @JsonProperty("format") ExportFormat format, @JsonProperty("dataSetName") String dataSetName, @JsonProperty("subVolumeMapping") Map subVolumeMapping) { diff --git a/vcell-core/src/test/java/cbit/vcell/export/N5ExporterTest.java b/vcell-core/src/test/java/cbit/vcell/export/N5ExporterTest.java index fbf7848a89..206836cd58 100644 --- a/vcell-core/src/test/java/cbit/vcell/export/N5ExporterTest.java +++ b/vcell-core/src/test/java/cbit/vcell/export/N5ExporterTest.java @@ -173,19 +173,18 @@ public void restore() throws IOException { } - public void makeN5FileWithSpecificSimulationResults(N5Specs.CompressionLevel compressionLevel, int startTimeIndex, int endTimeIndex, String modelID) throws Exception { + public void makeN5FileWithSpecificSimulationResults(int startTimeIndex, int endTimeIndex, String modelID) throws Exception { OutputContext outputContext = new OutputContext(new AnnotatedFunction[0]); VariableSpecs variableSpecs = new VariableSpecs(variables.stream().map(di -> di.getName()).toList(), ExportEnums.VariableMode.VARIABLE_MULTI); GeometrySpecs geometrySpecs = new GeometrySpecs(new SpatialSelection[0], 0, 0, ExportEnums.GeometryMode.GEOMETRY_SELECTIONS); - N5Specs n5Specs = new N5Specs(ExportEnums.ExportableDataType.PDE_VARIABLE_DATA, ExportFormat.N5, compressionLevel, modelID); + Map dummyMaskInfo = new HashMap<>(){{put(0, "Dummy"); put(1, "Test");}}; + N5Specs n5Specs = new N5Specs(ExportEnums.ExportableDataType.PDE_VARIABLE_DATA, ExportFormat.N5, modelID, dummyMaskInfo); double[] allTimes = dataServer.getDataSetTimes(testUser,n5Exporter.getVcDataID()); TimeSpecs timeSpecs = new TimeSpecs(startTimeIndex, endTimeIndex, allTimes, ExportEnums.TimeMode.TIME_RANGE); ExportSpecs exportSpecs = new ExportSpecs(n5Exporter.getVcDataID(), ExportFormat.N5, variableSpecs, timeSpecs, geometrySpecs, n5Specs, "", ""); - HashMap dummyMaskInfo = new HashMap<>(){{put(0, "Dummy"); put(1, "Test");}}; - exportSpecs.setExportMetaData(new HumanReadableExportData("", "", "", new ArrayList<>(), "", "", false, dummyMaskInfo)); FileDataContainerManager fileDataContainerManager = new FileDataContainerManager(); ExportOutput exportOutput = n5Exporter.makeN5Data(outputContext, Integer.parseInt(modelID), exportSpecs, fileDataContainerManager); @@ -223,7 +222,7 @@ public void testMetaData() throws Exception { for(TestModels model: TestModels.values()){ this.setExportTestState(model); - this.makeN5FileWithSpecificSimulationResults(N5Specs.CompressionLevel.RAW, 0, times.length - 1, model.simID); + this.makeN5FileWithSpecificSimulationResults(0, times.length - 1, model.simID); int sizeX = modelMesh.getSizeX(), sizeY = modelMesh.getSizeY(), @@ -290,7 +289,7 @@ private void compareData(N5Specs.CompressionLevel compressionLevel, TestModels m this.setExportTestState(model); OutputContext outputContext = new OutputContext(new AnnotatedFunction[0]); int endTimeIndex = times.length - 1; - makeN5FileWithSpecificSimulationResults(compressionLevel, 0, endTimeIndex, model.simID); + makeN5FileWithSpecificSimulationResults(0, endTimeIndex, model.simID); int sizeZ = postProcessVariable ? modelMesh.getSizeZ() : MeshToImage.newNumElements(modelMesh.getSizeZ()); int sizeX = postProcessVariable ? modelMesh.getSizeX() : MeshToImage.newNumElements(modelMesh.getSizeX()); diff --git a/vcell-rest/src/main/java/org/vcell/restq/activemq/ExportRequestListenerMQ.java b/vcell-rest/src/main/java/org/vcell/restq/activemq/ExportRequestListenerMQ.java index f8f2456367..1d12c6b7c1 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/activemq/ExportRequestListenerMQ.java +++ b/vcell-rest/src/main/java/org/vcell/restq/activemq/ExportRequestListenerMQ.java @@ -140,12 +140,8 @@ private ExportSpecs getExportSpecs(ExportJob exportJob) throws SQLException, Dat exportJob.geometrySpecs().sliceNumber(), exportJob.geometrySpecs().geometryMode()); } - Map subVolume = exportJob.formatSpecificSpecs() instanceof N5Specs n5ExportRequest ? - n5ExportRequest.getSubVolumeMapping() : null; - HumanReadableExportData humanReadableExportData = new HumanReadableExportData(null, - null, null, null, null, null, false, subVolume); return new ExportSpecs(new VCSimulationDataIdentifier(exportJob.simulationIdentifier(), exportJob.simulationJob()), exportJob.format(), exportJob.variableSpecs(), exportJob.timeSpecs(), - geometrySpecs, exportJob.formatSpecificSpecs(), exportJob.simulationName(), exportJob.contextName(), humanReadableExportData); + geometrySpecs, exportJob.formatSpecificSpecs(), exportJob.simulationName(), exportJob.contextName()); } public void setThreadWaitTimeUnit(TimeUnit timeUnit) { From 34ce7b1700f1930af977039736e37c3ade70b9b0 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Wed, 1 Apr 2026 10:42:26 -0400 Subject: [PATCH 48/65] Save Selected Z Slice --- .../src/main/resources/scripts/init.sql | 4 +-- .../restq/exports/ExportHistoryDBTest.java | 14 +++------- .../vcell/restq/exports/ExportServerTest.java | 6 +---- .../cbit/vcell/exports/ExportHistory.java | 8 +++--- .../vcell/exports/ExportHistoryDBDriver.java | 4 +-- .../vcell/exports/ExportHistoryDBRep.java | 10 ++++--- .../vcell/exports/ExportHistoryTable.java | 26 ++++++++----------- 7 files changed, 30 insertions(+), 42 deletions(-) diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 8dc92cc15a..17795fc210 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -91,8 +91,8 @@ CREATE TABLE vc_simulation_export_history ( variables text[] NOT NULL, start_time numeric NOT NULL, end_time numeric NOT NULL, - z_slice_start numeric NOT NULL, - z_slice_end numeric NOT NULL, + entire_z_stack numeric NOT NULL, + z_slice numeric, saved_file_name varchar(50) NOT NULL, event_status varchar(50) NOT NULL ); diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index ec5c67adc9..2978740534 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -19,10 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import io.quarkus.test.junit.QuarkusTest; import jakarta.inject.Inject; -import org.eclipse.microprofile.config.inject.ConfigProperty; import org.junit.jupiter.api.*; -import org.vcell.restclient.ApiClient; -import org.vcell.restclient.ApiException; import org.vcell.restq.TestEndpointUtils; import org.vcell.restq.config.CDIVCellConfigProvider; import org.vcell.restq.db.AgroalConnectionFactory; @@ -82,9 +79,6 @@ private ExportHistoryDBRep getExportHistoryRep(int jobID, String uri, Timestamp TimeSpecs timeSpecs = new TimeSpecs(0, 1, new double[]{0.0, 1.0}, ExportEnums.TimeMode.TIME_RANGE); VariableSpecs variableSpecs = new VariableSpecs(new String[]{"X"}, ExportEnums.VariableMode.VARIABLE_ONE); - N5Specs n5Specs = new N5Specs(ExportEnums.ExportableDataType.PDE_VARIABLE_DATA, ExportFormat.N5, - N5Specs.CompressionLevel.RAW, "test dataset name"); - List parameterValues = new ArrayList<>() {{ add(new HumanReadableExportData.DifferentParameterValues("parameter_name", "original_0", "changed_1")); @@ -95,7 +89,7 @@ private ExportHistoryDBRep getExportHistoryRep(int jobID, String uri, Timestamp jobID, savedBioModel.getVersion().getVersionKey(), null, savedSimulation.getKey(), savedSimulation.getMathDescription().getKey(), ExportFormat.N5, timestamp, uri, variableSpecs.getVariableNames(), - 1.2, 3.4, 1, 1, + 1.2, 3.4, false, 1, "nameOnServer", ExportEnums.ExportProgressType.EXPORT_COMPLETE ); } @@ -203,14 +197,14 @@ public void testGetExportHistory() throws SQLException, DataAccessException, Jso private boolean historyDBEqualHistory(ExportHistoryDBRep dbRep, ExportHistory history) { return dbRep.simulationRef().equals(history.simulationRef()) && dbRep.exportFormat().equals(history.exportFormat()) && - dbRep.exportDate().equals(history.exportDate()) && + history.exportDate().equals(dbRep.exportDate().toInstant()) && dbRep.uri().equals(history.uri()) && List.of(dbRep.variables()).equals(List.of(history.variables())) && Double.compare(dbRep.startTimeValue(), history.startTimeValue()) == 0 && Double.compare(dbRep.endTimeValue(), history.endTimeValue()) == 0 && dbRep.savedFileNameValue().equals(history.savedFileNameValue()) && dbRep.eventStatus().toString().equals(history.eventStatus().toString()) && - dbRep.zSliceStart() == history.zSliceStart() && - dbRep.zSliceEnd() == history.zSliceEnd(); + dbRep.selectedZSlice() == history.selectedZSlice() && + dbRep.entireZStack() == history.entireZStack(); } } diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java index d6917a6823..2aa9c3c3e1 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java @@ -222,10 +222,7 @@ private ExportSpecs getValidExportSpec(int startTimeIndex, int endTimeIndex) thr return new ExportSpecs(simulationDataIdentifier, ExportFormat.N5, request.standardExportInformation().variableSpecs(), request.standardExportInformation().timeSpecs(), new GeometrySpecs(geometrySpecs.selections(), geometrySpecs.axis(), geometrySpecs.sliceNumber(), geometrySpecs.geometryMode()), n5Specs, request.standardExportInformation().simulationName(), - request.standardExportInformation().contextName(), new HumanReadableExportData( - request.standardExportInformation().simulationName(), "fds", - "tretre", new ArrayList<>(), "fsdfds", - "fdsfsd", false, request.subVolume())); + request.standardExportInformation().contextName()); } private DataIdentifier getOneDIWithSpecificType(VariableType variableType, DataIdentifier[] dataIdentifiers){ @@ -238,7 +235,6 @@ private DataIdentifier getOneDIWithSpecificType(VariableType variableType, DataI } private Multi createExportListener(ExportSpecs exportSpecs, long jobID) throws Exception { - exportSpecs.setExportMetaData(new HumanReadableExportData("", "", "", new ArrayList<>(), "", "", false, dummyMaskInfo)); ExportResource.GeometrySpecDTO geometrySpecDTO = new ExportResource.GeometrySpecDTO(exportSpecs.getGeometrySpecs().getSelections(), exportSpecs.getGeometrySpecs().getAxis(), exportSpecs.getGeometrySpecs().getSliceNumber(), exportSpecs.getGeometrySpecs().getMode()); diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java index 498798179a..4485341c7f 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java @@ -4,13 +4,13 @@ import cbit.vcell.export.server.ExportFormat; import org.vcell.util.document.KeyValue; -import java.sql.Timestamp; +import java.time.Instant; public record ExportHistory( long exportJobID, KeyValue simulationRef, ExportFormat exportFormat, - Timestamp exportDate, + Instant exportDate, String uri, String simName, // String appName, @@ -21,8 +21,8 @@ public record ExportHistory( double endTimeValue, String savedFileNameValue, // String applicationTypeValue, - int zSliceStart, - int zSliceEnd, + int selectedZSlice, + boolean entireZStack, ExportEnums.ExportProgressType eventStatus ) { } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java index 0038afca1c..028e1565d2 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java @@ -52,8 +52,8 @@ public void addExportHistory(Connection conn, User user, ExportHistoryDBRep expo conn.createArrayOf("VARCHAR", exportHistory.variables()), exportHistory.startTimeValue(), exportHistory.endTimeValue(), - exportHistory.zSliceStart(), - exportHistory.zSliceEnd(), + exportHistory.entireZStack(), + exportHistory.selectedZSlice(), exportHistory.savedFileNameValue(), exportHistory.eventStatus().toString() ); diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java index 5282659db3..c8ee9ecada 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java @@ -23,8 +23,8 @@ public record ExportHistoryDBRep( String[] variables, double startTimeValue, double endTimeValue, - int zSliceStart, - int zSliceEnd, + boolean entireZStack, + int selectedZSlice, String savedFileNameValue, ExportEnums.ExportProgressType eventStatus ) { @@ -41,7 +41,9 @@ public boolean equals(ExportHistoryDBRep other){ Double.compare(this.endTimeValue, other.endTimeValue) == 0 && this.savedFileNameValue.equals(other.savedFileNameValue) && this.eventStatus.equals(other.eventStatus) && - this.zSliceStart == other.zSliceStart && - this.zSliceEnd == other.zSliceEnd; + this.entireZStack == other.entireZStack && + this.selectedZSlice == other.selectedZSlice; + } + } } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java index e86937636a..ce232e3323 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java @@ -7,14 +7,10 @@ import cbit.vcell.modeldb.BioModelTable; import cbit.vcell.modeldb.SimulationTable; import cbit.vcell.modeldb.UserTable; -import cbit.vcell.solver.MathOverrides; -import org.vcell.util.CommentStringTokenizer; import org.vcell.util.DataAccessException; -import org.vcell.util.document.BioModelChildSummary; import org.vcell.util.document.KeyValue; import java.sql.*; -import java.util.List; import java.util.StringJoiner; public class ExportHistoryTable extends Table { @@ -38,8 +34,8 @@ public class ExportHistoryTable extends Table { public final Field variables = new Field("variables", Field.SQLDataType.varchar_255, "[] NOT NULL"); public final Field startTime = new Field("start_time", Field.SQLDataType.number_as_real, "NOT NULL"); public final Field endTime = new Field("end_time", Field.SQLDataType.number_as_real, "NOT NULL"); - public final Field zSliceStart = new Field("z_slice_start", Field.SQLDataType.integer, "NOT NULL"); - public final Field zSliceEnd = new Field("z_slice_end", Field.SQLDataType.integer, "NOT NULL"); + public final Field entireZStack = new Field("entire_z_stack", Field.SQLDataType.integer, "NOT NULL CHECK (entire_z_stack IN (0,1))"); + public final Field selectedZSliceInStack = new Field("z_slice", Field.SQLDataType.integer, ""); public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_50, "NOT NULL"); public final Field eventStatus = new Field("event_status", Field.SQLDataType.varchar_50, "NOT NULL"); @@ -62,7 +58,7 @@ private ExportHistoryTable() { // note that primary key id cannot be placed in fields (will causes class initialization error), jobId, userRef, bioModelRef, mathModelRef, simulationRef, mathRef, exportFormat, exportDate, uri, variables, - startTime, endTime, zSliceStart, zSliceEnd, savedFileName, eventStatus + startTime, endTime, entireZStack, selectedZSliceInStack, savedFileName, eventStatus }; addFields(customFields); } @@ -97,8 +93,8 @@ public void bindForInsert( Array variables, double startTimeValue, double endTimeValue, - int zSliceStartValue, - int zSliceEndValue, + boolean entireZStack, + int selectedZSlice, String savedFileNameValue, String eventStatusValue ) throws SQLException { @@ -120,8 +116,8 @@ public void bindForInsert( ps.setArray (i++, variables); ps.setDouble (i++, startTimeValue); ps.setDouble (i++, endTimeValue); - ps.setInt (i++, zSliceStartValue); - ps.setInt (i++, zSliceEndValue); + ps.setInt (i++, entireZStack ? 1 : 0); + ps.setInt (i++, selectedZSlice); ps.setString (i++, savedFileNameValue); ps.setString (i++, eventStatusValue); } @@ -146,8 +142,8 @@ public ExportHistory getExportHistoryRecord(ResultSet rset) throws SQLException, // numeric ranges double startBt = rset.getDouble(this.startTime.getUnqualifiedColName()); double endBt = rset.getDouble(this.endTime.getUnqualifiedColName()); - int zS = rset.getInt(this.zSliceStart.getUnqualifiedColName()); - int zE = rset.getInt(this.zSliceEnd.getUnqualifiedColName()); + int zS = rset.getInt(this.selectedZSliceInStack.getUnqualifiedColName()); + int ez = rset.getInt(this.entireZStack.getUnqualifiedColName()); // more strings & flags String savedFileVal = rset.getString(this.savedFileName.getUnqualifiedColName()); @@ -165,10 +161,10 @@ public ExportHistory getExportHistoryRecord(ResultSet rset) throws SQLException, return new ExportHistory( - jobId, new KeyValue("" + simulationRef), fmt, date, + jobId, new KeyValue("" + simulationRef), fmt, date.toInstant(), uriVal, simNameVal, modelName, variables, startBt, endBt, savedFileVal, - zS, zE, ExportEnums.ExportProgressType.valueOf(eventStatusVal) + zS, ez == 1, ExportEnums.ExportProgressType.valueOf(eventStatusVal) ); } } From 94ccbddadf1833eaaa51eeafe4d5c8051b7c2806 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Wed, 1 Apr 2026 14:18:41 -0400 Subject: [PATCH 49/65] Export Panel Knows which Simulation --- .../src/main/java/cbit/vcell/client/data/PDEDataViewer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/PDEDataViewer.java b/vcell-client/src/main/java/cbit/vcell/client/data/PDEDataViewer.java index 5d4b366891..b5a97d16ef 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/PDEDataViewer.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/PDEDataViewer.java @@ -1970,6 +1970,7 @@ private PDEExportDataPanel getPDEExportPanel1() { try { ivjPDEExportPanel1 = new PDEExportDataPanel(); ivjPDEExportPanel1.setName("PDEExportPanel1"); + ivjPDEExportPanel1.setSimulation(getSimulation()); // user code begin {1} // user code end } catch (java.lang.Throwable ivjExc) { From b88b4271333dd08d2bf84565108d338ca7702bd3 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 2 Apr 2026 11:09:52 -0400 Subject: [PATCH 50/65] Export Spec Contains Model Keys --- .../main/java/org/vcell/cli/run/RunUtils.java | 3 ++- .../vcell/client/data/PDEExportDataPanel.java | 20 ++++++++++++------ .../cbit/vcell/export/server/ExportSpecs.java | 21 ++++++++++++++++++- .../cbit/vcell/export/server/IMGExporter.java | 4 +++- .../cbit/vcell/export/N5ExporterTest.java | 4 +++- .../activemq/ExportRequestListenerMQ.java | 7 +++++-- .../vcell/restq/handlers/ExportResource.java | 3 ++- .../restq/services/Exports/ExportService.java | 3 ++- 8 files changed, 51 insertions(+), 14 deletions(-) diff --git a/vcell-cli/src/main/java/org/vcell/cli/run/RunUtils.java b/vcell-cli/src/main/java/org/vcell/cli/run/RunUtils.java index 8e4ed71896..f5cf4efbce 100644 --- a/vcell-cli/src/main/java/org/vcell/cli/run/RunUtils.java +++ b/vcell-cli/src/main/java/org/vcell/cli/run/RunUtils.java @@ -455,7 +455,8 @@ private static ExportSpecs getExportSpecs(OutputContext outputContext, User user ExportFormat.CSV, ASCIISpecs.CsvRoiLayout.var_time_val, true, false); return new ExportSpecs(vcId, ExportFormat.HDF5, variableSpecs, timeSpecs, geometrySpecs, - formatSpecificSpecs, vcellSim.getName(), simContext.getBioModel().getName() + ":" + simContext.getName()); + formatSpecificSpecs, vcellSim.getName(), simContext.getBioModel().getName() + ":" + simContext.getName(), simContext.getBioModel().getVersion().getVersionKey(), + null, simContext.getMathDescription().getKey()); } } diff --git a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java index e6e1ddffb2..92c7fb06fb 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/client/data/PDEExportDataPanel.java @@ -32,10 +32,7 @@ import cbit.vcell.solver.*; import cbit.vcell.solvers.CartesianMesh; import org.vcell.util.UserCancelException; -import org.vcell.util.document.LocalVCDataIdentifier; -import org.vcell.util.document.User; -import org.vcell.util.document.VCDataIdentifier; -import org.vcell.util.document.VCDocument; +import org.vcell.util.document.*; import org.vcell.util.gui.*; import javax.swing.*; @@ -694,7 +691,15 @@ private ExportSpecs getExportSpecs() { throw new IllegalArgumentException("Expected " + SimulationContext.class.getName() + " or " + MathModel.class.getName()); } - return new ExportSpecs( + VCDocument thisDocument = (getDataViewerManager() instanceof DocumentWindowManager?((DocumentWindowManager)getDataViewerManager()).getVCDocument():null); + KeyValue bioModelKey = null; + KeyValue mathModelKey = null; + if (thisDocument != null){ + bioModelKey = thisDocument.getDocumentType() == VCDocument.VCDocumentType.BIOMODEL_DOC ? thisDocument.getVersion().getVersionKey() : null; + mathModelKey = thisDocument.getDocumentType() == VCDocument.VCDocumentType.MATHMODEL_DOC ? thisDocument.getVersion().getVersionKey() : null; + } + + return new ExportSpecs( vcDataIdentifier, getExportSettings1().getSelectedFormat(), variableSpecs, @@ -702,7 +707,10 @@ private ExportSpecs getExportSpecs() { geometrySpecs, getExportSettings1().getFormatSpecificSpecs(), dataInfoProvider.getSimulationModelInfo().getSimulationName(), - dataInfoProvider.getSimulationModelInfo().getContextName() + dataInfoProvider.getSimulationModelInfo().getContextName(), + bioModelKey, + mathModelKey, + getSimulation().getMathDescription().getKey() ); } diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java index 91279d127e..f9a37ba05a 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/ExportSpecs.java @@ -20,6 +20,7 @@ import org.vcell.util.BeanUtils; import org.vcell.util.Compare; import org.vcell.util.Range; +import org.vcell.util.document.KeyValue; import org.vcell.util.document.VCDataIdentifier; import cbit.image.DisplayAdapterService; @@ -38,6 +39,9 @@ public class ExportSpecs implements Serializable { private FormatSpecificSpecs formatSpecificSpecs; private String simulatioName; private String contextName; + private KeyValue bioModelKey; + private KeyValue mathModelKey; + private KeyValue mathDescriptionKey; public interface SimulationSelector{ public void selectSimulations(); @@ -52,7 +56,9 @@ public interface SimulationSelector{ public ExportSpecs(@JsonProperty("vcdataIdentifier") VCDataIdentifier vcdataIdentifier, @JsonProperty("format") ExportFormat format, @JsonProperty("variableSpecs") VariableSpecs variableSpecs, @JsonProperty("timeSpecs") TimeSpecs timeSpecs, @JsonProperty("geometrySpecs") GeometrySpecs geometrySpecs, @JsonProperty("formatSpecificSpecs") FormatSpecificSpecs formatSpecificSpecs, - @JsonProperty("simulationName") String simulationName, @JsonProperty("contextName") String contextName) { + @JsonProperty("simulationName") String simulationName, @JsonProperty("contextName") String contextName, + @JsonProperty("bioModelKey")KeyValue bioModelKey, @JsonProperty("mathModelKey") KeyValue mathModelKey, + @JsonProperty("mathDescriptionKey") KeyValue mathDescriptionKey) { this.vcDataIdentifier = vcdataIdentifier; this.format = format; this.variableSpecs = variableSpecs; @@ -61,6 +67,9 @@ public ExportSpecs(@JsonProperty("vcdataIdentifier") VCDataIdentifier vcdataIden this.formatSpecificSpecs = formatSpecificSpecs; this.simulatioName = simulationName; this.contextName = contextName; + this.bioModelKey = bioModelKey; + this.mathModelKey = mathModelKey; + this.mathDescriptionKey = mathDescriptionKey; } public String getContextName(){ @@ -150,6 +159,16 @@ public org.vcell.util.document.VCDataIdentifier getVCDataIdentifier() { return vcDataIdentifier; } + public KeyValue getBioModelKey() { + return bioModelKey; + } + public KeyValue getMathModelKey() { + return mathModelKey; + } + public KeyValue getMathDescriptionKey() { + return mathDescriptionKey; + } + /** * Insert the method's description here. diff --git a/vcell-core/src/main/java/cbit/vcell/export/server/IMGExporter.java b/vcell-core/src/main/java/cbit/vcell/export/server/IMGExporter.java index cc5b17e6f7..918e24196b 100644 --- a/vcell-core/src/main/java/cbit/vcell/export/server/IMGExporter.java +++ b/vcell-core/src/main/java/cbit/vcell/export/server/IMGExporter.java @@ -95,7 +95,9 @@ public static void main(String [] args) throws Exception{ MovieSpecs movieSpecs = new MovieSpecs( 1000.0, false, new DisplayPreferences[] {displayPreferences}, ExportFormat.FORMAT_JPEG, ExportEnums.MirroringMethod.NO_MIRRORING, 1, 1, 1,/// ImagePaneModel.MESH_MODE, FormatSpecificSpecs.CODEC_JPEG, 1.0f, false,FormatSpecificSpecs.PARTICLE_SELECT); - ExportSpecs exportSpecs = new ExportSpecs(vcdID, ExportFormat.QUICKTIME, variableSpecs, timeSpecs, geometrySpecs, movieSpecs,"IMGExporterTest",null); + ExportSpecs exportSpecs = new ExportSpecs(vcdID, ExportFormat.QUICKTIME, variableSpecs, timeSpecs, + geometrySpecs, movieSpecs,"IMGExporterTest",null, + null, null, null); exportServiceImpl.makeRemoteFile(null, user, dataServerImpl, exportSpecs); } diff --git a/vcell-core/src/test/java/cbit/vcell/export/N5ExporterTest.java b/vcell-core/src/test/java/cbit/vcell/export/N5ExporterTest.java index 206836cd58..74a8e21c45 100644 --- a/vcell-core/src/test/java/cbit/vcell/export/N5ExporterTest.java +++ b/vcell-core/src/test/java/cbit/vcell/export/N5ExporterTest.java @@ -184,7 +184,9 @@ public void makeN5FileWithSpecificSimulationResults(int startTimeIndex, int endT double[] allTimes = dataServer.getDataSetTimes(testUser,n5Exporter.getVcDataID()); TimeSpecs timeSpecs = new TimeSpecs(startTimeIndex, endTimeIndex, allTimes, ExportEnums.TimeMode.TIME_RANGE); - ExportSpecs exportSpecs = new ExportSpecs(n5Exporter.getVcDataID(), ExportFormat.N5, variableSpecs, timeSpecs, geometrySpecs, n5Specs, "", ""); + ExportSpecs exportSpecs = new ExportSpecs(n5Exporter.getVcDataID(), ExportFormat.N5, variableSpecs, timeSpecs, + geometrySpecs, n5Specs, "", "", + null, null, null); FileDataContainerManager fileDataContainerManager = new FileDataContainerManager(); ExportOutput exportOutput = n5Exporter.makeN5Data(outputContext, Integer.parseInt(modelID), exportSpecs, fileDataContainerManager); diff --git a/vcell-rest/src/main/java/org/vcell/restq/activemq/ExportRequestListenerMQ.java b/vcell-rest/src/main/java/org/vcell/restq/activemq/ExportRequestListenerMQ.java index 1d12c6b7c1..7e3772c297 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/activemq/ExportRequestListenerMQ.java +++ b/vcell-rest/src/main/java/org/vcell/restq/activemq/ExportRequestListenerMQ.java @@ -25,6 +25,7 @@ import org.vcell.restq.handlers.ExportResource; import org.vcell.restq.services.Exports.ServerExportEventController; import org.vcell.util.DataAccessException; +import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; import java.io.File; @@ -141,7 +142,8 @@ private ExportSpecs getExportSpecs(ExportJob exportJob) throws SQLException, Dat } return new ExportSpecs(new VCSimulationDataIdentifier(exportJob.simulationIdentifier(), exportJob.simulationJob()), exportJob.format(), exportJob.variableSpecs(), exportJob.timeSpecs(), - geometrySpecs, exportJob.formatSpecificSpecs(), exportJob.simulationName(), exportJob.contextName()); + geometrySpecs, exportJob.formatSpecificSpecs(), exportJob.simulationName(), exportJob.contextName(), + exportJob.bioModelKey(), exportJob.mathModelKey(), exportJob.mathDescriptionKey()); } public void setThreadWaitTimeUnit(TimeUnit timeUnit) { @@ -157,6 +159,7 @@ public record ExportJob( ExportFormat format, VariableSpecs variableSpecs, TimeSpecs timeSpecs, ExportResource.GeometrySpecDTO geometrySpecs, FormatSpecificSpecs formatSpecificSpecs, - String simulationName, String contextName + String simulationName, String contextName, + KeyValue bioModelKey, KeyValue mathModelKey, KeyValue mathDescriptionKey ){ } } diff --git a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java index 615c4a289c..4b2e1d930f 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java +++ b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java @@ -128,7 +128,8 @@ public record StandardExportInfo( ArrayList outputContext, String contextName, String simulationName, String simulationKey, int simulationJob, GeometrySpecDTO geometrySpecs, - TimeSpecs timeSpecs, VariableSpecs variableSpecs + TimeSpecs timeSpecs, VariableSpecs variableSpecs, + KeyValue bioModelKey, KeyValue mathModelKey, KeyValue mathDescriptionKey ){ } public record AnnotatedFunctionDTO( diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java index 85e2233eba..135989f1f1 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java @@ -78,7 +78,8 @@ public ExportRequestListenerMQ.ExportJob createExportJobFromRequest(User user, E ).toArray(AnnotatedFunction[]::new); } return new ExportRequestListenerMQ.ExportJob(exportID, user, annotatedFunctions, simulationIdentifier, request.simulationJob(), format, - request.variableSpecs(), request.timeSpecs(), request.geometrySpecs(), formatSpecificSpecs, request.simulationName(), request.contextName()); + request.variableSpecs(), request.timeSpecs(), request.geometrySpecs(), formatSpecificSpecs, request.simulationName(), request.contextName(), + request.bioModelKey(), request.mathModelKey(), request.mathDescriptionKey()); } } From 19390cca95e5a1bdb7eaeef1476aa235dd25ea43 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 2 Apr 2026 11:15:43 -0400 Subject: [PATCH 51/65] Insert Frap Model Util Function --- .../org/vcell/restq/TestEndpointUtils.java | 27 ++++++++++++++++--- .../org/vcell/restq/exports/ExportHelper.java | 8 +++--- .../restq/exports/ExportHistoryDBTest.java | 10 ++----- .../restq/exports/ExportRequestTest.java | 22 +-------------- .../vcell/restq/exports/ExportServerTest.java | 25 +++++++++++------ 5 files changed, 48 insertions(+), 44 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java index d40fccd6e6..aa73b22739 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -7,7 +7,6 @@ import cbit.vcell.model.Kinetics; import cbit.vcell.model.SimpleReaction; import cbit.vcell.model.SpeciesContext; -import cbit.vcell.modeldb.AdminDBTopLevel; import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.parser.Expression; import cbit.vcell.resource.PropertyLoader; @@ -33,8 +32,7 @@ import org.vcell.restq.exports.ExportRequestTest; import org.vcell.util.BigString; import org.vcell.util.DataAccessException; -import org.vcell.util.document.KeyValue; -import org.vcell.util.document.User; +import org.vcell.util.document.*; import java.beans.PropertyVetoException; import java.io.File; @@ -216,7 +214,8 @@ public static void clearAllBioModelEntries(AgroalConnectionFactory agroalConnect connection.close(); } - public static void insertAdminsSimulation(DatabaseServerImpl databaseServer, AgroalConnectionFactory connectionFactory) throws IOException, DataAccessException, SQLException, PropertyVetoException, XmlParseException { + public static BioModel insertFrapModel(AgroalConnectionFactory connectionFactory) throws IOException, DataAccessException, SQLException, PropertyVetoException, XmlParseException { + DatabaseServerImpl databaseServer = new DatabaseServerImpl(connectionFactory, connectionFactory.getKeyFactory()); InputStream xmlFile = TestEndpointUtils.class.getResourceAsStream("/simdata/Administrator/Tutorial_FRAP.vcml"); assert xmlFile != null; BigString bioModelString = new BigString(new String(xmlFile.readAllBytes())); @@ -235,6 +234,26 @@ public static void insertAdminsSimulation(DatabaseServerImpl databaseServer, Agr ).executeUpdate(); connection.commit(); connection.close(); + Simulation originalSim = bioModel.getSimulation(0); + Simulation updatedSim = new Simulation( + new SimulationVersion( + new KeyValue("597714292"), + originalSim.getVersion().getName(), + originalSim.getVersion().getOwner(), + new GroupAccessAll(), + originalSim.getVersion().getBranchPointRefKey(), + originalSim.getVersion().getBranchID(), + originalSim.getVersion().getDate(), + originalSim.getVersion().getFlag(), + originalSim.getVersion().getAnnot(), + null + ), + originalSim.getMathDescription(), + originalSim.getSimulationOwner() + ); + bioModel.removeSimulation(originalSim); + bioModel.addSimulation(updatedSim); + return bioModel; } diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java index 583fb67583..7e49061c48 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java @@ -29,10 +29,10 @@ public class ExportHelper { private static final Logger lg = LogManager.getLogger(ExportRequestTest.class); - public static void exportAndWait(ExportResourceApi exportResourceApi, N5ExportRequest n5ExportRequest) throws ApiException { + public static ExportEvent exportAndWait(ExportResourceApi exportResourceApi, N5ExportRequest n5ExportRequest) throws ApiException { final long time = Instant.now().getEpochSecond(); // Before export even starts, so that all events are grabbed from the queue long jobId = exportResourceApi.exportN5(n5ExportRequest); - CompletableFuture future = CompletableFuture.runAsync(() -> { + CompletableFuture future = CompletableFuture.supplyAsync(() -> { try{ List allEvents = new ArrayList<>(); while (allEvents.isEmpty()){ @@ -50,11 +50,13 @@ public static void exportAndWait(ExportResourceApi exportResourceApi, N5ExportRe Thread.sleep(500); } Assertions.assertEquals(ExportProgressType.COMPLETE, eventUnderInspection.getEventType()); + return eventUnderInspection; } catch (Exception e){ Assertions.fail(); } + throw new RuntimeException("This should never be reached"); }).orTimeout(20, TimeUnit.SECONDS); - future.join(); + return future.join(); } private static ExportEvent getLastEventForJob(List events, long jobId){ diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index 2978740534..de4ac5f666 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -59,14 +59,8 @@ public static void setupConfig() { } @BeforeEach - public void initializeDB() throws DataAccessException, PropertyVetoException, XmlParseException, IOException, ExpressionException { - DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); - BioModel bioModel = TestEndpointUtils.getTestBioModel(); - bioModel.getSimulation(0).getMathOverrides().putConstant(new Constant("Dex_diffusionRate", new Expression(20))); - bioModel.getSimulation(0).getMathOverrides().putConstant(new Constant("Voltage_PM", new Expression(2))); - BigString bioModelXML = databaseServer.saveBioModel(TestEndpointUtils.administratorUser, new BigString(XmlHelper.bioModelToXML(bioModel)), new String[]{}); - savedBioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelXML.toString())); - + public void initializeDB() throws DataAccessException, PropertyVetoException, XmlParseException, IOException, ExpressionException, SQLException { + savedBioModel = TestEndpointUtils.insertFrapModel(agroalConnectionFactory); savedSimulation = savedBioModel.getSimulation(0); simulationKey = savedSimulation.getVersion().getVersionKey(); } diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java index e63b8a26ee..3d85df4a46 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java @@ -1,20 +1,12 @@ package org.vcell.restq.exports; -import cbit.vcell.export.server.ExportEnums; -import cbit.vcell.math.VariableType; import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.resource.PropertyLoader; -import cbit.vcell.simdata.DataIdentifier; import cbit.vcell.simdata.*; -import cbit.vcell.solver.AnnotatedFunction; -import cbit.vcell.solver.VCSimulationDataIdentifier; -import cbit.vcell.solver.VCSimulationIdentifier; import cbit.vcell.xml.XmlParseException; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.keycloak.client.KeycloakTestClient; import jakarta.inject.Inject; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.junit.jupiter.api.*; import org.vcell.restclient.ApiClient; @@ -24,22 +16,11 @@ import org.vcell.restq.TestEndpointUtils; import org.vcell.restq.config.CDIVCellConfigProvider; import org.vcell.restq.db.AgroalConnectionFactory; -import org.vcell.restq.handlers.AdminResource; import org.vcell.util.DataAccessException; -import org.vcell.util.document.KeyValue; import java.beans.PropertyVetoException; -import java.io.File; import java.io.IOException; import java.sql.SQLException; -import java.time.Instant; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; import static org.vcell.restq.exports.ExportHelper.getValidExportRequestDTO; @@ -65,9 +46,8 @@ public static void setupConfig(){ public void setUp() throws IOException, DataAccessException, ApiException, SQLException, PropertyVetoException, XmlParseException { aliceAPIClient = TestEndpointUtils.createAuthenticatedAPIClient(keycloakClient, testPort, TestEndpointUtils.TestOIDCUsers.alice); TestEndpointUtils.mapApiClientToAdmin(aliceAPIClient); - DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); dataServer = TestEndpointUtils.createDataServerImpl(); - TestEndpointUtils.insertAdminsSimulation(databaseServer, agroalConnectionFactory); + TestEndpointUtils.insertFrapModel(agroalConnectionFactory); } @AfterEach diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java index 2aa9c3c3e1..fc46c24246 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportServerTest.java @@ -1,9 +1,11 @@ package org.vcell.restq.exports; import cbit.rmi.event.ExportEvent; +import cbit.vcell.biomodel.BioModel; import cbit.vcell.export.server.*; import cbit.vcell.math.VariableType; import cbit.vcell.modeldb.DatabaseServerImpl; +import cbit.vcell.parser.ExpressionException; import cbit.vcell.resource.PropertyLoader; import cbit.vcell.simdata.*; import cbit.vcell.solver.AnnotatedFunction; @@ -56,6 +58,7 @@ public class ExportServerTest { @Inject ObjectMapper mapper; + private BioModel bioModel; private DataServerImpl dataServer; private final String simulationID = "597714292"; private final HashMap dummyMaskInfo = new HashMap<>(){{put(0, "Dummy"); put(1, "Test");}}; @@ -66,14 +69,14 @@ public static void setupConfig() throws JMSException { } @BeforeEach - public void setUp() throws IOException, DataAccessException, SQLException, PropertyVetoException, XmlParseException { + public void setUp() throws IOException, DataAccessException, SQLException, PropertyVetoException, XmlParseException, ExpressionException { File testSimData = new File(ExportServerTest.class.getResource("/simdata").getPath()); TestEndpointUtils.setSystemProperties(testSimData.getAbsolutePath(), System.getProperty("java.io.tmpdir")); Cachetable cachetable = new Cachetable(10 * Cachetable.minute, 10000); DataSetControllerImpl dataSetController = new DataSetControllerImpl(cachetable, testSimData, testSimData); dataServer = new DataServerImpl(dataSetController, null); - DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); - TestEndpointUtils.insertAdminsSimulation(databaseServer, agroalConnectionFactory); + + bioModel = TestEndpointUtils.insertFrapModel(agroalConnectionFactory); } @AfterEach @@ -141,13 +144,16 @@ public void testInvalidInputException() throws Exception { ExportSpecs exportSpecs = getValidExportSpec(0, 1); long badJobID = 2; ExportSpecs badExportSpecs = new ExportSpecs(exportSpecs.getVCDataIdentifier(), ExportFormat.N5, null, null, - new GeometrySpecs(new SpatialSelection[]{}, -1, 5000, ExportEnums.GeometryMode.GEOMETRY_SLICE), null, "TestSim", null); + new GeometrySpecs(new SpatialSelection[]{}, -1, 5000, ExportEnums.GeometryMode.GEOMETRY_SLICE), + null, "TestSim", null, null, null, null); Multi status = createExportListener(badExportSpecs, badJobID); // Start job, while having it be blocking on the main thread to check status CompletableFuture future = CompletableFuture.runAsync(() -> { VCSimulationDataIdentifier vcSimulationDataIdentifier = (VCSimulationDataIdentifier) exportSpecs.getVCDataIdentifier(); - ExportRequestListenerMQ.ExportJob exportJob = new ExportRequestListenerMQ.ExportJob(badJobID, TestEndpointUtils.administratorUser, new AnnotatedFunction[]{}, vcSimulationDataIdentifier.getVcSimID(), vcSimulationDataIdentifier.getJobIndex(), null, null, null, null, null,"TestSim", null); + ExportRequestListenerMQ.ExportJob exportJob = new ExportRequestListenerMQ.ExportJob(badJobID, TestEndpointUtils.administratorUser, new AnnotatedFunction[]{}, vcSimulationDataIdentifier.getVcSimID(), vcSimulationDataIdentifier.getJobIndex(), + null, null, null, null, null,"TestSim", null, + bioModel.getVersion().getVersionKey(), null, bioModel.getSimulationContext(0).getMathDescription().getKey()); CompletableFuture job = null; try { job = requestListenerMQ.get().startJob(Message.of(mapper.writeValueAsString(exportJob))); @@ -208,7 +214,8 @@ private ExportResource.N5ExportRequest getValidExportRequest(int startTimeIndex, HashMap dummyMaskInfo = new HashMap<>(){{put(0, "Dummy"); put(1, "Test");}}; ExportResource.StandardExportInfo request = new ExportResource.StandardExportInfo(new ArrayList<>(){},"", "TestSim", simulationID, 0, - geometrySpecs, timeSpecs, variableSpecs); + geometrySpecs, timeSpecs, variableSpecs, + bioModel.getVersion().getVersionKey(), null, bioModel.getSimulationContext(0).getMathDescription().getKey()); return new ExportResource.N5ExportRequest(request, dummyMaskInfo, ExportEnums.ExportableDataType.PDE_VARIABLE_DATA, "TestDataset"); } @@ -222,7 +229,8 @@ private ExportSpecs getValidExportSpec(int startTimeIndex, int endTimeIndex) thr return new ExportSpecs(simulationDataIdentifier, ExportFormat.N5, request.standardExportInformation().variableSpecs(), request.standardExportInformation().timeSpecs(), new GeometrySpecs(geometrySpecs.selections(), geometrySpecs.axis(), geometrySpecs.sliceNumber(), geometrySpecs.geometryMode()), n5Specs, request.standardExportInformation().simulationName(), - request.standardExportInformation().contextName()); + request.standardExportInformation().contextName(), + bioModel.getVersion().getVersionKey(), null, bioModel.getSimulationContext(0).getMathDescription().getKey()); } private DataIdentifier getOneDIWithSpecificType(VariableType variableType, DataIdentifier[] dataIdentifiers){ @@ -241,7 +249,8 @@ private Multi createExportListener(ExportSpecs exportSpecs, long jo VCSimulationDataIdentifier vcSimulationDataIdentifier = (VCSimulationDataIdentifier) exportSpecs.getVCDataIdentifier(); ExportRequestListenerMQ.ExportJob exportJob = new ExportRequestListenerMQ.ExportJob(jobID, TestEndpointUtils.administratorUser, new AnnotatedFunction[]{}, vcSimulationDataIdentifier.getVcSimID(), vcSimulationDataIdentifier.getJobIndex(), exportSpecs.getFormat(), exportSpecs.getVariableSpecs(), exportSpecs.getTimeSpecs(), - geometrySpecDTO, exportSpecs.getFormatSpecificSpecs(), exportSpecs.getSimulationName(), exportSpecs.getContextName()); + geometrySpecDTO, exportSpecs.getFormatSpecificSpecs(), exportSpecs.getSimulationName(), exportSpecs.getContextName(), + bioModel.getVersion().getVersionKey(), null, bioModel.getSimulationContext(0).getMathDescription().getKey()); statusCreator.get().addServerExportListener(exportJob); return statusCreator.get().getSSEUsersExportStatus(TestEndpointUtils.administratorUser, exportJob.id()); From 0cace6480dae77298bfc00dd9dd0b473de77b6e9 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 6 Apr 2026 10:17:02 -0400 Subject: [PATCH 52/65] Export History Contains Model Keys --- .../vcell/microscopy/gui/FRAPStudyPanel.java | 4 +++- .../cbit/vcell/exports/ExportHistory.java | 3 +++ .../vcell/exports/ExportHistoryDBRep.java | 20 +++++++++++++++++++ .../vcell/exports/ExportHistoryTable.java | 8 ++++++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/vcell-client/src/main/java/cbit/vcell/microscopy/gui/FRAPStudyPanel.java b/vcell-client/src/main/java/cbit/vcell/microscopy/gui/FRAPStudyPanel.java index 5184191cb0..490abb226c 100644 --- a/vcell-client/src/main/java/cbit/vcell/microscopy/gui/FRAPStudyPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/microscopy/gui/FRAPStudyPanel.java @@ -1393,7 +1393,9 @@ public void run(Hashtable hashTable) throws Exception false, FormatSpecificSpecs.PARTICLE_NONE); // mSpec.setViewZoom(1); - ExportSpecs exSpecs = new ExportSpecs(vcDataId, format, variableSpecs, timeSpecs, geometrySpecs, mSpec,fStudy.getName(),null); + BioModel bioModel = getFrapWorkspace().getWorkingFrapStudy().getBioModel(); + ExportSpecs exSpecs = new ExportSpecs(vcDataId, format, variableSpecs, timeSpecs, geometrySpecs, mSpec,fStudy.getName(),null, + bioModel.getVersion().getVersionKey(), null, sim.getMathDescription().getKey()); // pass the request ExportEvent exportEvt = ((VirtualFrapWindowManager)getFlourDataViewer().getDataViewerManager()).startExportMovie(exSpecs, outputContext, this.getClientTaskStatusSupport()); hashTable.put("ExportEvt", exportEvt); diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java index 4485341c7f..87fea31cf7 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java @@ -9,6 +9,9 @@ public record ExportHistory( long exportJobID, KeyValue simulationRef, + KeyValue bioModelRef, + KeyValue mathModelRef, + KeyValue mathRef, ExportFormat exportFormat, Instant exportDate, String uri, diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java index c8ee9ecada..070dacffed 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java @@ -45,5 +45,25 @@ public boolean equals(ExportHistoryDBRep other){ this.selectedZSlice == other.selectedZSlice; } + public static ExportHistoryDBRep fromExportSpec(ExportSpecs exportSpecs, String url, long jobID, VCSimulationDataIdentifier simDataId, ExportEnums.ExportProgressType eventStatus) { + double[] times = exportSpecs.getTimeSpecs().getAllTimes(); + boolean entireZStack = exportSpecs.getGeometrySpecs().getMode() == ExportEnums.GeometryMode.GEOMETRY_FULL; + return new ExportHistoryDBRep( + (int) jobID, + exportSpecs.getBioModelKey(), + exportSpecs.getMathModelKey(), + simDataId.getSimulationKey(), + exportSpecs.getMathDescriptionKey(), + exportSpecs.getFormat(), + Timestamp.from(Instant.now()), + url, + exportSpecs.getVariableSpecs().getVariableNames(), + times[exportSpecs.getTimeSpecs().getBeginTimeIndex()], + times[exportSpecs.getTimeSpecs().getEndTimeIndex()], + entireZStack, + entireZStack ? exportSpecs.getGeometrySpecs().getSliceNumber() : -1, + null, + eventStatus + ); } } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java index ce232e3323..b7049e3acb 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java @@ -36,7 +36,7 @@ public class ExportHistoryTable extends Table { public final Field endTime = new Field("end_time", Field.SQLDataType.number_as_real, "NOT NULL"); public final Field entireZStack = new Field("entire_z_stack", Field.SQLDataType.integer, "NOT NULL CHECK (entire_z_stack IN (0,1))"); public final Field selectedZSliceInStack = new Field("z_slice", Field.SQLDataType.integer, ""); - public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_50, "NOT NULL"); + public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_50, ""); public final Field eventStatus = new Field("event_status", Field.SQLDataType.varchar_50, "NOT NULL"); @@ -125,6 +125,9 @@ public void bindForInsert( public ExportHistory getExportHistoryRecord(ResultSet rset) throws SQLException, SQLException, DataAccessException { long simulationRef = rset.getLong(this.simulationRef.getUnqualifiedColName()); + long mathRef = rset.getLong(this.mathRef.getUnqualifiedColName()); + Long bioModelRef = (Long) rset.getObject(this.bioModelRef.getUnqualifiedColName()); + Long mathModelRef = (Long) rset.getObject(this.mathModelRef.getUnqualifiedColName()); // enums & timestamps ExportFormat fmt = ExportFormat.valueOf(rset.getString(this.exportFormat.getUnqualifiedColName())); Timestamp date = rset.getTimestamp(this.exportDate.getUnqualifiedColName()); @@ -161,7 +164,8 @@ public ExportHistory getExportHistoryRecord(ResultSet rset) throws SQLException, return new ExportHistory( - jobId, new KeyValue("" + simulationRef), fmt, date.toInstant(), + jobId, new KeyValue("" + simulationRef), bioModelRef == null ? null : new KeyValue("" + bioModelRef), + mathModelRef == null ? null : new KeyValue("" + mathModelRef), new KeyValue("" + mathRef), fmt, date.toInstant(), uriVal, simNameVal, modelName, variables, startBt, endBt, savedFileVal, zS, ez == 1, ExportEnums.ExportProgressType.valueOf(eventStatusVal) From 3ae049246319286d11c0ee97c03a0b2bfd21bfc5 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 6 Apr 2026 10:19:31 -0400 Subject: [PATCH 53/65] Export History Endpoint --- .../vcell/restq/handlers/ExportResource.java | 30 +------------------ .../restq/services/Exports/ExportService.java | 6 ++-- .../Exports/ServerExportEventController.java | 25 ++++++++++++++-- 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java index 4b2e1d930f..75be121068 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java +++ b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java @@ -2,6 +2,7 @@ import cbit.rmi.event.ExportEvent; import cbit.vcell.export.server.*; +import cbit.vcell.exports.ExportHistory; import cbit.vcell.math.Variable; import cbit.vcell.math.VariableType; import cbit.vcell.exports.ExportHistoryDBRep; @@ -141,35 +142,6 @@ public record AnnotatedFunctionDTO( AnnotatedFunction.FunctionCategory category ) { } - public record ExportHistory( - int jobID, - KeyValue simulationRef, - ExportFormat exportFormat, - String exportDate, - String uri, - String dataIdValue, - String simName, - String appName, - String bioName, - String[] variables, - List parameterValues, - double startTimeValue, - double endTimeValue, - String savedFileNameValue, - String applicationTypeValue, - boolean nonSpatialValue, - int zSlicesValue, - int tSlicesValue, - int numVariablesValue - ){ - public static ExportHistory fromExportHistoryRep(ExportHistoryDBRep rep){ - return new ExportHistory(rep.jobID(), rep.simulationRef(), rep.exportFormat(), rep.exportDate().toString(), rep.uri(), rep.dataIdValue(), - rep.simName(), rep.appName(), rep.bioName(), rep.variables(), rep.parameterValues(), rep.startTimeValue(), - rep.endTimeValue(), rep.savedFileNameValue(), rep.applicationTypeValue(), rep.nonSpatialValue(), - rep.zSlicesValue(), rep.tSlicesValue(), rep.numVariablesValue()); - } - } - public record GeometrySpecDTO( SpatialSelection[] selections, int axis, int sliceNumber, ExportEnums.GeometryMode geometryMode ){ } diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java index 135989f1f1..075999f575 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java @@ -5,6 +5,7 @@ import cbit.vcell.export.server.ExportFormat; import cbit.vcell.export.server.FormatSpecificSpecs; import cbit.vcell.export.server.JobRequest; +import cbit.vcell.exports.ExportHistory; import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.exports.ExportHistoryDBRep; import cbit.vcell.modeldb.SimulationRep; @@ -46,9 +47,8 @@ public ExportService(AgroalConnectionFactory connectionFactory) throws DataAcces databaseServer = new DatabaseServerImpl(connectionFactory, connectionFactory.getKeyFactory()); } - public List getExportHistory(User user) throws DataAccessException { - List exportHistoryDBReps = databaseServer.getUsersExportHistory(user); - return exportHistoryDBReps.stream().map(ExportResource.ExportHistory::fromExportHistoryRep).toList(); + public List getExportHistory(User user) throws DataAccessException { + return databaseServer.getUsersExportHistory(user); } public Multi getExportStatuses(User user, long jobID) throws ObjectNotFoundException { diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java index 6db1315e42..e65ff5d43c 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java @@ -6,7 +6,7 @@ import cbit.vcell.export.server.ExportEnums; import cbit.vcell.export.server.ExportSpecs; import cbit.vcell.modeldb.DatabaseServerImpl; -import cbit.vcell.exports.ExportHistoryRep; +import cbit.vcell.exports.ExportHistoryDBRep; import cbit.vcell.solver.VCSimulationDataIdentifier; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -20,6 +20,8 @@ import org.eclipse.microprofile.reactive.messaging.Channel; import org.eclipse.microprofile.reactive.messaging.Emitter; import org.vcell.restq.activemq.ExportRequestListenerMQ; +import org.vcell.restq.db.AgroalConnectionFactory; +import org.vcell.util.DataAccessException; import org.vcell.util.ObjectNotFoundException; import org.vcell.util.document.ExternalDataIdentifier; import org.vcell.util.document.KeyValue; @@ -64,6 +66,7 @@ public class ServerExportEventController implements cbit.rmi.event.ExportEventCo private final ConcurrentHashMap> listeners = new ConcurrentHashMap<>(); private final static Logger logger = LogManager.getLogger(ServerExportEventController.class); + private final DatabaseServerImpl databaseServerImpl; @Inject @Channel("publisher-client-status") @@ -72,6 +75,12 @@ public class ServerExportEventController implements cbit.rmi.event.ExportEventCo @Inject ObjectMapper objectMapper; + @Inject + public ServerExportEventController(AgroalConnectionFactory agroalConnectionFactory) throws DataAccessException { + databaseServerImpl = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); + + } + public synchronized Multi getSSEUsersExportStatus(User user, long exportJobID) throws ObjectNotFoundException { String key = sseEventListenerKey(user, exportJobID); @@ -142,7 +151,19 @@ public synchronized ExportEvent fireExportCompleted(long jobID, VCDataIdentifier ExportEvent event = new ExportEvent( this, jobID, user, vcdID.getID(), dataKey, ExportEnums.ExportProgressType.EXPORT_COMPLETE, format, location, null); - event.setHumanReadableExportData(exportSpecs != null ? exportSpecs.getHumanReadableExportData() : null); + + if (exportSpecs != null && exportSpecs.getVCDataIdentifier() instanceof VCSimulationDataIdentifier vcSimulationDataIdentifier){ + try{ + databaseServerImpl.addExportHistory(user, ExportHistoryDBRep.fromExportSpec(exportSpecs, location, (int) jobID, vcSimulationDataIdentifier, ExportEnums.ExportProgressType.EXPORT_COMPLETE)); + } catch (DataAccessException e) { + logger.error("Couldn't add export history to database for user " + user.getName() + ", job id " + jobID + + ", and export spec " + exportSpecs, e); + } + } else { + logger.warn("ExportSpecs was null or did not contain a VCSimulationDataIdentifier, " + + "so export history was not added to the database for user {}, job id {}, and export spec {}", user.getName(), jobID, exportSpecs); + } + fireExportEvent(event); return event; From 9234a8d66dca39867fb1b376d1e436bcb9ee0fc4 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 6 Apr 2026 10:28:28 -0400 Subject: [PATCH 54/65] Generated Clients --- python-restclient/.openapi-generator/FILES | 3 - python-restclient/docs/ExportHistory.md | 20 +- python-restclient/docs/StandardExportInfo.md | 3 + .../vcell_client/models/export_history.py | 51 +- .../models/standard_export_info.py | 10 +- tools/openapi.yaml | 44 +- vcell-restclient/.openapi-generator/FILES | 3 - vcell-restclient/api/openapi.yaml | 76 ++- vcell-restclient/docs/ExportHistory.md | 20 +- vcell-restclient/docs/StandardExportInfo.md | 3 + .../vcell/restclient/model/ExportHistory.java | 494 ++++++++---------- .../restclient/model/StandardExportInfo.java | 114 +++- .../modules/openapi/model/export-history.ts | 20 +- .../openapi/model/standard-export-info.ts | 3 + 14 files changed, 438 insertions(+), 426 deletions(-) diff --git a/python-restclient/.openapi-generator/FILES b/python-restclient/.openapi-generator/FILES index 8ff2641798..54329b8441 100644 --- a/python-restclient/.openapi-generator/FILES +++ b/python-restclient/.openapi-generator/FILES @@ -102,9 +102,6 @@ docs/VariableType.md docs/Version.md docs/VersionFlag.md test/__init__.py -test/test_different_parameter_values.py -test/test_export_format.py -test/test_export_history.py tox.ini vcell_client/__init__.py vcell_client/api/__init__.py diff --git a/python-restclient/docs/ExportHistory.md b/python-restclient/docs/ExportHistory.md index c44a1c621c..1e216d1762 100644 --- a/python-restclient/docs/ExportHistory.md +++ b/python-restclient/docs/ExportHistory.md @@ -4,25 +4,23 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**job_id** | **int** | | [optional] +**export_job_id** | **int** | | [optional] **simulation_ref** | **str** | | [optional] +**bio_model_ref** | **str** | | [optional] +**math_model_ref** | **str** | | [optional] +**math_ref** | **str** | | [optional] **export_format** | [**ExportFormat**](ExportFormat.md) | | [optional] -**export_date** | **str** | | [optional] +**export_date** | **datetime** | | [optional] **uri** | **str** | | [optional] -**data_id_value** | **str** | | [optional] **sim_name** | **str** | | [optional] -**app_name** | **str** | | [optional] -**bio_name** | **str** | | [optional] +**model_name** | **str** | | [optional] **variables** | **List[str]** | | [optional] -**parameter_values** | [**List[DifferentParameterValues]**](DifferentParameterValues.md) | | [optional] **start_time_value** | **float** | | [optional] **end_time_value** | **float** | | [optional] **saved_file_name_value** | **str** | | [optional] -**application_type_value** | **str** | | [optional] -**non_spatial_value** | **bool** | | [optional] -**z_slices_value** | **int** | | [optional] -**t_slices_value** | **int** | | [optional] -**num_variables_value** | **int** | | [optional] +**selected_z_slice** | **int** | | [optional] +**entire_z_stack** | **bool** | | [optional] +**event_status** | [**ExportProgressType**](ExportProgressType.md) | | [optional] ## Example diff --git a/python-restclient/docs/StandardExportInfo.md b/python-restclient/docs/StandardExportInfo.md index da7a8f6e8e..bfac077b60 100644 --- a/python-restclient/docs/StandardExportInfo.md +++ b/python-restclient/docs/StandardExportInfo.md @@ -12,6 +12,9 @@ Name | Type | Description | Notes **geometry_specs** | [**GeometrySpecDTO**](GeometrySpecDTO.md) | | [optional] **time_specs** | [**TimeSpecs**](TimeSpecs.md) | | [optional] **variable_specs** | [**VariableSpecs**](VariableSpecs.md) | | [optional] +**bio_model_key** | **str** | | [optional] +**math_model_key** | **str** | | [optional] +**math_description_key** | **str** | | [optional] ## Example diff --git a/python-restclient/vcell_client/models/export_history.py b/python-restclient/vcell_client/models/export_history.py index a0bbff38da..b411bd1997 100644 --- a/python-restclient/vcell_client/models/export_history.py +++ b/python-restclient/vcell_client/models/export_history.py @@ -18,12 +18,12 @@ import re # noqa: F401 import json - +from datetime import datetime from typing import Any, ClassVar, Dict, List, Optional, Union from pydantic import BaseModel, StrictBool, StrictFloat, StrictInt, StrictStr from pydantic import Field -from vcell_client.models.different_parameter_values import DifferentParameterValues from vcell_client.models.export_format import ExportFormat +from vcell_client.models.export_progress_type import ExportProgressType try: from typing import Self except ImportError: @@ -33,26 +33,24 @@ class ExportHistory(BaseModel): """ ExportHistory """ # noqa: E501 - job_id: Optional[StrictInt] = Field(default=None, alias="jobID") + export_job_id: Optional[StrictInt] = Field(default=None, alias="exportJobID") simulation_ref: Optional[StrictStr] = Field(default=None, alias="simulationRef") + bio_model_ref: Optional[StrictStr] = Field(default=None, alias="bioModelRef") + math_model_ref: Optional[StrictStr] = Field(default=None, alias="mathModelRef") + math_ref: Optional[StrictStr] = Field(default=None, alias="mathRef") export_format: Optional[ExportFormat] = Field(default=None, alias="exportFormat") - export_date: Optional[StrictStr] = Field(default=None, alias="exportDate") + export_date: Optional[datetime] = Field(default=None, alias="exportDate") uri: Optional[StrictStr] = None - data_id_value: Optional[StrictStr] = Field(default=None, alias="dataIdValue") sim_name: Optional[StrictStr] = Field(default=None, alias="simName") - app_name: Optional[StrictStr] = Field(default=None, alias="appName") - bio_name: Optional[StrictStr] = Field(default=None, alias="bioName") + model_name: Optional[StrictStr] = Field(default=None, alias="modelName") variables: Optional[List[StrictStr]] = None - parameter_values: Optional[List[DifferentParameterValues]] = Field(default=None, alias="parameterValues") start_time_value: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="startTimeValue") end_time_value: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="endTimeValue") saved_file_name_value: Optional[StrictStr] = Field(default=None, alias="savedFileNameValue") - application_type_value: Optional[StrictStr] = Field(default=None, alias="applicationTypeValue") - non_spatial_value: Optional[StrictBool] = Field(default=None, alias="nonSpatialValue") - z_slices_value: Optional[StrictInt] = Field(default=None, alias="zSlicesValue") - t_slices_value: Optional[StrictInt] = Field(default=None, alias="tSlicesValue") - num_variables_value: Optional[StrictInt] = Field(default=None, alias="numVariablesValue") - __properties: ClassVar[List[str]] = ["jobID", "simulationRef", "exportFormat", "exportDate", "uri", "dataIdValue", "simName", "appName", "bioName", "variables", "parameterValues", "startTimeValue", "endTimeValue", "savedFileNameValue", "applicationTypeValue", "nonSpatialValue", "zSlicesValue", "tSlicesValue", "numVariablesValue"] + selected_z_slice: Optional[StrictInt] = Field(default=None, alias="selectedZSlice") + entire_z_stack: Optional[StrictBool] = Field(default=None, alias="entireZStack") + event_status: Optional[ExportProgressType] = Field(default=None, alias="eventStatus") + __properties: ClassVar[List[str]] = ["exportJobID", "simulationRef", "bioModelRef", "mathModelRef", "mathRef", "exportFormat", "exportDate", "uri", "simName", "modelName", "variables", "startTimeValue", "endTimeValue", "savedFileNameValue", "selectedZSlice", "entireZStack", "eventStatus"] model_config = { "populate_by_name": True, @@ -90,13 +88,6 @@ def to_dict(self) -> Dict[str, Any]: }, exclude_none=True, ) - # override the default output from pydantic by calling `to_dict()` of each item in parameter_values (list) - _items = [] - if self.parameter_values: - for _item in self.parameter_values: - if _item: - _items.append(_item.to_dict()) - _dict['parameterValues'] = _items return _dict @classmethod @@ -114,25 +105,23 @@ def from_dict(cls, obj: Dict) -> Self: raise ValueError("Error due to additional fields (not defined in ExportHistory) in the input: " + _key) _obj = cls.model_validate({ - "jobID": obj.get("jobID"), + "exportJobID": obj.get("exportJobID"), "simulationRef": obj.get("simulationRef"), + "bioModelRef": obj.get("bioModelRef"), + "mathModelRef": obj.get("mathModelRef"), + "mathRef": obj.get("mathRef"), "exportFormat": obj.get("exportFormat"), "exportDate": obj.get("exportDate"), "uri": obj.get("uri"), - "dataIdValue": obj.get("dataIdValue"), "simName": obj.get("simName"), - "appName": obj.get("appName"), - "bioName": obj.get("bioName"), + "modelName": obj.get("modelName"), "variables": obj.get("variables"), - "parameterValues": [DifferentParameterValues.from_dict(_item) for _item in obj.get("parameterValues")] if obj.get("parameterValues") is not None else None, "startTimeValue": obj.get("startTimeValue"), "endTimeValue": obj.get("endTimeValue"), "savedFileNameValue": obj.get("savedFileNameValue"), - "applicationTypeValue": obj.get("applicationTypeValue"), - "nonSpatialValue": obj.get("nonSpatialValue"), - "zSlicesValue": obj.get("zSlicesValue"), - "tSlicesValue": obj.get("tSlicesValue"), - "numVariablesValue": obj.get("numVariablesValue") + "selectedZSlice": obj.get("selectedZSlice"), + "entireZStack": obj.get("entireZStack"), + "eventStatus": obj.get("eventStatus") }) return _obj diff --git a/python-restclient/vcell_client/models/standard_export_info.py b/python-restclient/vcell_client/models/standard_export_info.py index 3244390068..bd0db9c0b8 100644 --- a/python-restclient/vcell_client/models/standard_export_info.py +++ b/python-restclient/vcell_client/models/standard_export_info.py @@ -43,7 +43,10 @@ class StandardExportInfo(BaseModel): geometry_specs: Optional[GeometrySpecDTO] = Field(default=None, alias="geometrySpecs") time_specs: Optional[TimeSpecs] = Field(default=None, alias="timeSpecs") variable_specs: Optional[VariableSpecs] = Field(default=None, alias="variableSpecs") - __properties: ClassVar[List[str]] = ["outputContext", "contextName", "simulationName", "simulationKey", "simulationJob", "geometrySpecs", "timeSpecs", "variableSpecs"] + bio_model_key: Optional[StrictStr] = Field(default=None, alias="bioModelKey") + math_model_key: Optional[StrictStr] = Field(default=None, alias="mathModelKey") + math_description_key: Optional[StrictStr] = Field(default=None, alias="mathDescriptionKey") + __properties: ClassVar[List[str]] = ["outputContext", "contextName", "simulationName", "simulationKey", "simulationJob", "geometrySpecs", "timeSpecs", "variableSpecs", "bioModelKey", "mathModelKey", "mathDescriptionKey"] model_config = { "populate_by_name": True, @@ -121,7 +124,10 @@ def from_dict(cls, obj: Dict) -> Self: "simulationJob": obj.get("simulationJob"), "geometrySpecs": GeometrySpecDTO.from_dict(obj.get("geometrySpecs")) if obj.get("geometrySpecs") is not None else None, "timeSpecs": TimeSpecs.from_dict(obj.get("timeSpecs")) if obj.get("timeSpecs") is not None else None, - "variableSpecs": VariableSpecs.from_dict(obj.get("variableSpecs")) if obj.get("variableSpecs") is not None else None + "variableSpecs": VariableSpecs.from_dict(obj.get("variableSpecs")) if obj.get("variableSpecs") is not None else None, + "bioModelKey": obj.get("bioModelKey"), + "mathModelKey": obj.get("mathModelKey"), + "mathDescriptionKey": obj.get("mathDescriptionKey") }) return _obj diff --git a/tools/openapi.yaml b/tools/openapi.yaml index 1a6233252d..cb35d4c41e 100644 --- a/tools/openapi.yaml +++ b/tools/openapi.yaml @@ -2577,33 +2577,31 @@ components: ExportHistory: type: object properties: - jobID: - format: int32 + exportJobID: + format: int64 type: integer simulationRef: $ref: '#/components/schemas/KeyValue' + bioModelRef: + $ref: '#/components/schemas/KeyValue' + mathModelRef: + $ref: '#/components/schemas/KeyValue' + mathRef: + $ref: '#/components/schemas/KeyValue' exportFormat: $ref: '#/components/schemas/ExportFormat' exportDate: - type: string + $ref: '#/components/schemas/Instant' uri: type: string - dataIdValue: - type: string simName: type: string - appName: - type: string - bioName: + modelName: type: string variables: type: array items: type: string - parameterValues: - type: array - items: - $ref: '#/components/schemas/DifferentParameterValues' startTimeValue: format: double type: number @@ -2612,19 +2610,13 @@ components: type: number savedFileNameValue: type: string - applicationTypeValue: - type: string - nonSpatialValue: - type: boolean - zSlicesValue: - format: int32 - type: integer - tSlicesValue: - format: int32 - type: integer - numVariablesValue: + selectedZSlice: format: int32 type: integer + entireZStack: + type: boolean + eventStatus: + $ref: '#/components/schemas/ExportProgressType' ExportProgressType: enum: - EXPORT_START @@ -3368,6 +3360,12 @@ components: $ref: '#/components/schemas/TimeSpecs' variableSpecs: $ref: '#/components/schemas/VariableSpecs' + bioModelKey: + $ref: '#/components/schemas/KeyValue' + mathModelKey: + $ref: '#/components/schemas/KeyValue' + mathDescriptionKey: + $ref: '#/components/schemas/KeyValue' Status: enum: - UNKNOWN diff --git a/vcell-restclient/.openapi-generator/FILES b/vcell-restclient/.openapi-generator/FILES index 6741c43cb0..9b23d83a2f 100644 --- a/vcell-restclient/.openapi-generator/FILES +++ b/vcell-restclient/.openapi-generator/FILES @@ -212,6 +212,3 @@ src/main/java/org/vcell/restclient/model/VariableSpecs.java src/main/java/org/vcell/restclient/model/VariableType.java src/main/java/org/vcell/restclient/model/Version.java src/main/java/org/vcell/restclient/model/VersionFlag.java -src/test/java/org/vcell/restclient/model/DifferentParameterValuesTest.java -src/test/java/org/vcell/restclient/model/ExportFormatTest.java -src/test/java/org/vcell/restclient/model/ExportHistoryTest.java diff --git a/vcell-restclient/api/openapi.yaml b/vcell-restclient/api/openapi.yaml index 1da74fe0cb..d6a2f08b92 100644 --- a/vcell-restclient/api/openapi.yaml +++ b/vcell-restclient/api/openapi.yaml @@ -3004,61 +3004,53 @@ components: type: string ExportHistory: example: + mathModelRef: mathModelRef variables: - variables - variables - bioName: bioName - applicationTypeValue: applicationTypeValue simulationRef: simulationRef - numVariablesValue: 2 - appName: appName + mathRef: mathRef startTimeValue: 6.027456183070403 endTimeValue: 1.4658129805029452 uri: uri - jobID: 0 - exportDate: exportDate + modelName: modelName + exportDate: 2022-03-10T16:15:50Z savedFileNameValue: savedFileNameValue - nonSpatialValue: true - zSlicesValue: 5 + entireZStack: true + selectedZSlice: 5 + eventStatus: null simName: simName + exportJobID: 0 + bioModelRef: bioModelRef exportFormat: null - tSlicesValue: 5 - dataIdValue: dataIdValue - parameterValues: - - originalValue: originalValue - parameterName: parameterName - changedValue: changedValue - - originalValue: originalValue - parameterName: parameterName - changedValue: changedValue properties: - jobID: - format: int32 + exportJobID: + format: int64 type: integer simulationRef: type: string + bioModelRef: + type: string + mathModelRef: + type: string + mathRef: + type: string exportFormat: $ref: '#/components/schemas/ExportFormat' exportDate: + example: 2022-03-10T16:15:50Z + format: date-time type: string uri: type: string - dataIdValue: - type: string simName: type: string - appName: - type: string - bioName: + modelName: type: string variables: items: type: string type: array - parameterValues: - items: - $ref: '#/components/schemas/DifferentParameterValues' - type: array startTimeValue: format: double type: number @@ -3067,19 +3059,13 @@ components: type: number savedFileNameValue: type: string - applicationTypeValue: - type: string - nonSpatialValue: - type: boolean - zSlicesValue: - format: int32 - type: integer - tSlicesValue: - format: int32 - type: integer - numVariablesValue: + selectedZSlice: format: int32 type: integer + entireZStack: + type: boolean + eventStatus: + $ref: '#/components/schemas/ExportProgressType' type: object ExportProgressType: enum: @@ -3918,6 +3904,8 @@ components: variableNames: - variableNames - variableNames + bioModelKey: bioModelKey + mathDescriptionKey: mathDescriptionKey simulationName: simulationName geometrySpecs: selections: @@ -4028,6 +4016,7 @@ components: sliceNumber: 4 geometryMode: null axis: 1 + mathModelKey: mathModelKey outputContext: - functionName: functionName domain: @@ -4600,6 +4589,8 @@ components: variableNames: - variableNames - variableNames + bioModelKey: bioModelKey + mathDescriptionKey: mathDescriptionKey simulationName: simulationName geometrySpecs: selections: @@ -4710,6 +4701,7 @@ components: sliceNumber: 4 geometryMode: null axis: 1 + mathModelKey: mathModelKey outputContext: - functionName: functionName domain: @@ -4771,6 +4763,12 @@ components: $ref: '#/components/schemas/TimeSpecs' variableSpecs: $ref: '#/components/schemas/VariableSpecs' + bioModelKey: + type: string + mathModelKey: + type: string + mathDescriptionKey: + type: string type: object Status: enum: diff --git a/vcell-restclient/docs/ExportHistory.md b/vcell-restclient/docs/ExportHistory.md index 14658914ff..600c70906d 100644 --- a/vcell-restclient/docs/ExportHistory.md +++ b/vcell-restclient/docs/ExportHistory.md @@ -7,25 +7,23 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| -|**jobID** | **Integer** | | [optional] | +|**exportJobID** | **Long** | | [optional] | |**simulationRef** | **String** | | [optional] | +|**bioModelRef** | **String** | | [optional] | +|**mathModelRef** | **String** | | [optional] | +|**mathRef** | **String** | | [optional] | |**exportFormat** | **ExportFormat** | | [optional] | -|**exportDate** | **String** | | [optional] | +|**exportDate** | **OffsetDateTime** | | [optional] | |**uri** | **String** | | [optional] | -|**dataIdValue** | **String** | | [optional] | |**simName** | **String** | | [optional] | -|**appName** | **String** | | [optional] | -|**bioName** | **String** | | [optional] | +|**modelName** | **String** | | [optional] | |**variables** | **List<String>** | | [optional] | -|**parameterValues** | [**List<DifferentParameterValues>**](DifferentParameterValues.md) | | [optional] | |**startTimeValue** | **Double** | | [optional] | |**endTimeValue** | **Double** | | [optional] | |**savedFileNameValue** | **String** | | [optional] | -|**applicationTypeValue** | **String** | | [optional] | -|**nonSpatialValue** | **Boolean** | | [optional] | -|**zSlicesValue** | **Integer** | | [optional] | -|**tSlicesValue** | **Integer** | | [optional] | -|**numVariablesValue** | **Integer** | | [optional] | +|**selectedZSlice** | **Integer** | | [optional] | +|**entireZStack** | **Boolean** | | [optional] | +|**eventStatus** | **ExportProgressType** | | [optional] | diff --git a/vcell-restclient/docs/StandardExportInfo.md b/vcell-restclient/docs/StandardExportInfo.md index 42fbfc49cb..459bcc7715 100644 --- a/vcell-restclient/docs/StandardExportInfo.md +++ b/vcell-restclient/docs/StandardExportInfo.md @@ -15,6 +15,9 @@ |**geometrySpecs** | [**GeometrySpecDTO**](GeometrySpecDTO.md) | | [optional] | |**timeSpecs** | [**TimeSpecs**](TimeSpecs.md) | | [optional] | |**variableSpecs** | [**VariableSpecs**](VariableSpecs.md) | | [optional] | +|**bioModelKey** | **String** | | [optional] | +|**mathModelKey** | **String** | | [optional] | +|**mathDescriptionKey** | **String** | | [optional] | diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java index 4f923f6727..0011cfa365 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java @@ -24,11 +24,12 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonValue; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.vcell.restclient.model.DifferentParameterValues; import org.vcell.restclient.model.ExportFormat; +import org.vcell.restclient.model.ExportProgressType; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @@ -36,61 +37,59 @@ * ExportHistory */ @JsonPropertyOrder({ - ExportHistory.JSON_PROPERTY_JOB_I_D, + ExportHistory.JSON_PROPERTY_EXPORT_JOB_I_D, ExportHistory.JSON_PROPERTY_SIMULATION_REF, + ExportHistory.JSON_PROPERTY_BIO_MODEL_REF, + ExportHistory.JSON_PROPERTY_MATH_MODEL_REF, + ExportHistory.JSON_PROPERTY_MATH_REF, ExportHistory.JSON_PROPERTY_EXPORT_FORMAT, ExportHistory.JSON_PROPERTY_EXPORT_DATE, ExportHistory.JSON_PROPERTY_URI, - ExportHistory.JSON_PROPERTY_DATA_ID_VALUE, ExportHistory.JSON_PROPERTY_SIM_NAME, - ExportHistory.JSON_PROPERTY_APP_NAME, - ExportHistory.JSON_PROPERTY_BIO_NAME, + ExportHistory.JSON_PROPERTY_MODEL_NAME, ExportHistory.JSON_PROPERTY_VARIABLES, - ExportHistory.JSON_PROPERTY_PARAMETER_VALUES, ExportHistory.JSON_PROPERTY_START_TIME_VALUE, ExportHistory.JSON_PROPERTY_END_TIME_VALUE, ExportHistory.JSON_PROPERTY_SAVED_FILE_NAME_VALUE, - ExportHistory.JSON_PROPERTY_APPLICATION_TYPE_VALUE, - ExportHistory.JSON_PROPERTY_NON_SPATIAL_VALUE, - ExportHistory.JSON_PROPERTY_Z_SLICES_VALUE, - ExportHistory.JSON_PROPERTY_T_SLICES_VALUE, - ExportHistory.JSON_PROPERTY_NUM_VARIABLES_VALUE + ExportHistory.JSON_PROPERTY_SELECTED_Z_SLICE, + ExportHistory.JSON_PROPERTY_ENTIRE_Z_STACK, + ExportHistory.JSON_PROPERTY_EVENT_STATUS }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class ExportHistory { - public static final String JSON_PROPERTY_JOB_I_D = "jobID"; - private Integer jobID; + public static final String JSON_PROPERTY_EXPORT_JOB_I_D = "exportJobID"; + private Long exportJobID; public static final String JSON_PROPERTY_SIMULATION_REF = "simulationRef"; private String simulationRef; + public static final String JSON_PROPERTY_BIO_MODEL_REF = "bioModelRef"; + private String bioModelRef; + + public static final String JSON_PROPERTY_MATH_MODEL_REF = "mathModelRef"; + private String mathModelRef; + + public static final String JSON_PROPERTY_MATH_REF = "mathRef"; + private String mathRef; + public static final String JSON_PROPERTY_EXPORT_FORMAT = "exportFormat"; private ExportFormat exportFormat; public static final String JSON_PROPERTY_EXPORT_DATE = "exportDate"; - private String exportDate; + private OffsetDateTime exportDate; public static final String JSON_PROPERTY_URI = "uri"; private String uri; - public static final String JSON_PROPERTY_DATA_ID_VALUE = "dataIdValue"; - private String dataIdValue; - public static final String JSON_PROPERTY_SIM_NAME = "simName"; private String simName; - public static final String JSON_PROPERTY_APP_NAME = "appName"; - private String appName; - - public static final String JSON_PROPERTY_BIO_NAME = "bioName"; - private String bioName; + public static final String JSON_PROPERTY_MODEL_NAME = "modelName"; + private String modelName; public static final String JSON_PROPERTY_VARIABLES = "variables"; private List variables; - public static final String JSON_PROPERTY_PARAMETER_VALUES = "parameterValues"; - private List parameterValues; - public static final String JSON_PROPERTY_START_TIME_VALUE = "startTimeValue"; private Double startTimeValue; @@ -100,46 +99,40 @@ public class ExportHistory { public static final String JSON_PROPERTY_SAVED_FILE_NAME_VALUE = "savedFileNameValue"; private String savedFileNameValue; - public static final String JSON_PROPERTY_APPLICATION_TYPE_VALUE = "applicationTypeValue"; - private String applicationTypeValue; - - public static final String JSON_PROPERTY_NON_SPATIAL_VALUE = "nonSpatialValue"; - private Boolean nonSpatialValue; - - public static final String JSON_PROPERTY_Z_SLICES_VALUE = "zSlicesValue"; - private Integer zSlicesValue; + public static final String JSON_PROPERTY_SELECTED_Z_SLICE = "selectedZSlice"; + private Integer selectedZSlice; - public static final String JSON_PROPERTY_T_SLICES_VALUE = "tSlicesValue"; - private Integer tSlicesValue; + public static final String JSON_PROPERTY_ENTIRE_Z_STACK = "entireZStack"; + private Boolean entireZStack; - public static final String JSON_PROPERTY_NUM_VARIABLES_VALUE = "numVariablesValue"; - private Integer numVariablesValue; + public static final String JSON_PROPERTY_EVENT_STATUS = "eventStatus"; + private ExportProgressType eventStatus; public ExportHistory() { } - public ExportHistory jobID(Integer jobID) { - this.jobID = jobID; + public ExportHistory exportJobID(Long exportJobID) { + this.exportJobID = exportJobID; return this; } /** - * Get jobID - * @return jobID + * Get exportJobID + * @return exportJobID **/ @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_JOB_I_D) + @JsonProperty(JSON_PROPERTY_EXPORT_JOB_I_D) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public Integer getJobID() { - return jobID; + public Long getExportJobID() { + return exportJobID; } - @JsonProperty(JSON_PROPERTY_JOB_I_D) + @JsonProperty(JSON_PROPERTY_EXPORT_JOB_I_D) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setJobID(Integer jobID) { - this.jobID = jobID; + public void setExportJobID(Long exportJobID) { + this.exportJobID = exportJobID; } @@ -168,6 +161,81 @@ public void setSimulationRef(String simulationRef) { } + public ExportHistory bioModelRef(String bioModelRef) { + this.bioModelRef = bioModelRef; + return this; + } + + /** + * Get bioModelRef + * @return bioModelRef + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_BIO_MODEL_REF) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getBioModelRef() { + return bioModelRef; + } + + + @JsonProperty(JSON_PROPERTY_BIO_MODEL_REF) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setBioModelRef(String bioModelRef) { + this.bioModelRef = bioModelRef; + } + + + public ExportHistory mathModelRef(String mathModelRef) { + this.mathModelRef = mathModelRef; + return this; + } + + /** + * Get mathModelRef + * @return mathModelRef + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_MATH_MODEL_REF) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getMathModelRef() { + return mathModelRef; + } + + + @JsonProperty(JSON_PROPERTY_MATH_MODEL_REF) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMathModelRef(String mathModelRef) { + this.mathModelRef = mathModelRef; + } + + + public ExportHistory mathRef(String mathRef) { + this.mathRef = mathRef; + return this; + } + + /** + * Get mathRef + * @return mathRef + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_MATH_REF) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getMathRef() { + return mathRef; + } + + + @JsonProperty(JSON_PROPERTY_MATH_REF) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMathRef(String mathRef) { + this.mathRef = mathRef; + } + + public ExportHistory exportFormat(ExportFormat exportFormat) { this.exportFormat = exportFormat; return this; @@ -193,7 +261,7 @@ public void setExportFormat(ExportFormat exportFormat) { } - public ExportHistory exportDate(String exportDate) { + public ExportHistory exportDate(OffsetDateTime exportDate) { this.exportDate = exportDate; return this; } @@ -206,14 +274,14 @@ public ExportHistory exportDate(String exportDate) { @JsonProperty(JSON_PROPERTY_EXPORT_DATE) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public String getExportDate() { + public OffsetDateTime getExportDate() { return exportDate; } @JsonProperty(JSON_PROPERTY_EXPORT_DATE) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setExportDate(String exportDate) { + public void setExportDate(OffsetDateTime exportDate) { this.exportDate = exportDate; } @@ -243,31 +311,6 @@ public void setUri(String uri) { } - public ExportHistory dataIdValue(String dataIdValue) { - this.dataIdValue = dataIdValue; - return this; - } - - /** - * Get dataIdValue - * @return dataIdValue - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_DATA_ID_VALUE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public String getDataIdValue() { - return dataIdValue; - } - - - @JsonProperty(JSON_PROPERTY_DATA_ID_VALUE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setDataIdValue(String dataIdValue) { - this.dataIdValue = dataIdValue; - } - - public ExportHistory simName(String simName) { this.simName = simName; return this; @@ -293,53 +336,28 @@ public void setSimName(String simName) { } - public ExportHistory appName(String appName) { - this.appName = appName; + public ExportHistory modelName(String modelName) { + this.modelName = modelName; return this; } /** - * Get appName - * @return appName + * Get modelName + * @return modelName **/ @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_APP_NAME) + @JsonProperty(JSON_PROPERTY_MODEL_NAME) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public String getAppName() { - return appName; + public String getModelName() { + return modelName; } - @JsonProperty(JSON_PROPERTY_APP_NAME) + @JsonProperty(JSON_PROPERTY_MODEL_NAME) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setAppName(String appName) { - this.appName = appName; - } - - - public ExportHistory bioName(String bioName) { - this.bioName = bioName; - return this; - } - - /** - * Get bioName - * @return bioName - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_BIO_NAME) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public String getBioName() { - return bioName; - } - - - @JsonProperty(JSON_PROPERTY_BIO_NAME) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setBioName(String bioName) { - this.bioName = bioName; + public void setModelName(String modelName) { + this.modelName = modelName; } @@ -376,39 +394,6 @@ public void setVariables(List variables) { } - public ExportHistory parameterValues(List parameterValues) { - this.parameterValues = parameterValues; - return this; - } - - public ExportHistory addParameterValuesItem(DifferentParameterValues parameterValuesItem) { - if (this.parameterValues == null) { - this.parameterValues = new ArrayList<>(); - } - this.parameterValues.add(parameterValuesItem); - return this; - } - - /** - * Get parameterValues - * @return parameterValues - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_PARAMETER_VALUES) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public List getParameterValues() { - return parameterValues; - } - - - @JsonProperty(JSON_PROPERTY_PARAMETER_VALUES) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setParameterValues(List parameterValues) { - this.parameterValues = parameterValues; - } - - public ExportHistory startTimeValue(Double startTimeValue) { this.startTimeValue = startTimeValue; return this; @@ -484,128 +469,78 @@ public void setSavedFileNameValue(String savedFileNameValue) { } - public ExportHistory applicationTypeValue(String applicationTypeValue) { - this.applicationTypeValue = applicationTypeValue; - return this; - } - - /** - * Get applicationTypeValue - * @return applicationTypeValue - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_APPLICATION_TYPE_VALUE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public String getApplicationTypeValue() { - return applicationTypeValue; - } - - - @JsonProperty(JSON_PROPERTY_APPLICATION_TYPE_VALUE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setApplicationTypeValue(String applicationTypeValue) { - this.applicationTypeValue = applicationTypeValue; - } - - - public ExportHistory nonSpatialValue(Boolean nonSpatialValue) { - this.nonSpatialValue = nonSpatialValue; + public ExportHistory selectedZSlice(Integer selectedZSlice) { + this.selectedZSlice = selectedZSlice; return this; } /** - * Get nonSpatialValue - * @return nonSpatialValue + * Get selectedZSlice + * @return selectedZSlice **/ @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_NON_SPATIAL_VALUE) + @JsonProperty(JSON_PROPERTY_SELECTED_Z_SLICE) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public Boolean getNonSpatialValue() { - return nonSpatialValue; + public Integer getSelectedZSlice() { + return selectedZSlice; } - @JsonProperty(JSON_PROPERTY_NON_SPATIAL_VALUE) + @JsonProperty(JSON_PROPERTY_SELECTED_Z_SLICE) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setNonSpatialValue(Boolean nonSpatialValue) { - this.nonSpatialValue = nonSpatialValue; + public void setSelectedZSlice(Integer selectedZSlice) { + this.selectedZSlice = selectedZSlice; } - public ExportHistory zSlicesValue(Integer zSlicesValue) { - this.zSlicesValue = zSlicesValue; + public ExportHistory entireZStack(Boolean entireZStack) { + this.entireZStack = entireZStack; return this; } /** - * Get zSlicesValue - * @return zSlicesValue + * Get entireZStack + * @return entireZStack **/ @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_Z_SLICES_VALUE) + @JsonProperty(JSON_PROPERTY_ENTIRE_Z_STACK) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public Integer getzSlicesValue() { - return zSlicesValue; + public Boolean getEntireZStack() { + return entireZStack; } - @JsonProperty(JSON_PROPERTY_Z_SLICES_VALUE) + @JsonProperty(JSON_PROPERTY_ENTIRE_Z_STACK) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setzSlicesValue(Integer zSlicesValue) { - this.zSlicesValue = zSlicesValue; + public void setEntireZStack(Boolean entireZStack) { + this.entireZStack = entireZStack; } - public ExportHistory tSlicesValue(Integer tSlicesValue) { - this.tSlicesValue = tSlicesValue; + public ExportHistory eventStatus(ExportProgressType eventStatus) { + this.eventStatus = eventStatus; return this; } /** - * Get tSlicesValue - * @return tSlicesValue + * Get eventStatus + * @return eventStatus **/ @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_T_SLICES_VALUE) + @JsonProperty(JSON_PROPERTY_EVENT_STATUS) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public Integer gettSlicesValue() { - return tSlicesValue; + public ExportProgressType getEventStatus() { + return eventStatus; } - @JsonProperty(JSON_PROPERTY_T_SLICES_VALUE) + @JsonProperty(JSON_PROPERTY_EVENT_STATUS) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void settSlicesValue(Integer tSlicesValue) { - this.tSlicesValue = tSlicesValue; - } - - - public ExportHistory numVariablesValue(Integer numVariablesValue) { - this.numVariablesValue = numVariablesValue; - return this; - } - - /** - * Get numVariablesValue - * @return numVariablesValue - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_NUM_VARIABLES_VALUE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public Integer getNumVariablesValue() { - return numVariablesValue; - } - - - @JsonProperty(JSON_PROPERTY_NUM_VARIABLES_VALUE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setNumVariablesValue(Integer numVariablesValue) { - this.numVariablesValue = numVariablesValue; + public void setEventStatus(ExportProgressType eventStatus) { + this.eventStatus = eventStatus; } @@ -621,55 +556,51 @@ public boolean equals(Object o) { return false; } ExportHistory exportHistory = (ExportHistory) o; - return Objects.equals(this.jobID, exportHistory.jobID) && + return Objects.equals(this.exportJobID, exportHistory.exportJobID) && Objects.equals(this.simulationRef, exportHistory.simulationRef) && + Objects.equals(this.bioModelRef, exportHistory.bioModelRef) && + Objects.equals(this.mathModelRef, exportHistory.mathModelRef) && + Objects.equals(this.mathRef, exportHistory.mathRef) && Objects.equals(this.exportFormat, exportHistory.exportFormat) && Objects.equals(this.exportDate, exportHistory.exportDate) && Objects.equals(this.uri, exportHistory.uri) && - Objects.equals(this.dataIdValue, exportHistory.dataIdValue) && Objects.equals(this.simName, exportHistory.simName) && - Objects.equals(this.appName, exportHistory.appName) && - Objects.equals(this.bioName, exportHistory.bioName) && + Objects.equals(this.modelName, exportHistory.modelName) && Objects.equals(this.variables, exportHistory.variables) && - Objects.equals(this.parameterValues, exportHistory.parameterValues) && Objects.equals(this.startTimeValue, exportHistory.startTimeValue) && Objects.equals(this.endTimeValue, exportHistory.endTimeValue) && Objects.equals(this.savedFileNameValue, exportHistory.savedFileNameValue) && - Objects.equals(this.applicationTypeValue, exportHistory.applicationTypeValue) && - Objects.equals(this.nonSpatialValue, exportHistory.nonSpatialValue) && - Objects.equals(this.zSlicesValue, exportHistory.zSlicesValue) && - Objects.equals(this.tSlicesValue, exportHistory.tSlicesValue) && - Objects.equals(this.numVariablesValue, exportHistory.numVariablesValue); + Objects.equals(this.selectedZSlice, exportHistory.selectedZSlice) && + Objects.equals(this.entireZStack, exportHistory.entireZStack) && + Objects.equals(this.eventStatus, exportHistory.eventStatus); } @Override public int hashCode() { - return Objects.hash(jobID, simulationRef, exportFormat, exportDate, uri, dataIdValue, simName, appName, bioName, variables, parameterValues, startTimeValue, endTimeValue, savedFileNameValue, applicationTypeValue, nonSpatialValue, zSlicesValue, tSlicesValue, numVariablesValue); + return Objects.hash(exportJobID, simulationRef, bioModelRef, mathModelRef, mathRef, exportFormat, exportDate, uri, simName, modelName, variables, startTimeValue, endTimeValue, savedFileNameValue, selectedZSlice, entireZStack, eventStatus); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class ExportHistory {\n"); - sb.append(" jobID: ").append(toIndentedString(jobID)).append("\n"); + sb.append(" exportJobID: ").append(toIndentedString(exportJobID)).append("\n"); sb.append(" simulationRef: ").append(toIndentedString(simulationRef)).append("\n"); + sb.append(" bioModelRef: ").append(toIndentedString(bioModelRef)).append("\n"); + sb.append(" mathModelRef: ").append(toIndentedString(mathModelRef)).append("\n"); + sb.append(" mathRef: ").append(toIndentedString(mathRef)).append("\n"); sb.append(" exportFormat: ").append(toIndentedString(exportFormat)).append("\n"); sb.append(" exportDate: ").append(toIndentedString(exportDate)).append("\n"); sb.append(" uri: ").append(toIndentedString(uri)).append("\n"); - sb.append(" dataIdValue: ").append(toIndentedString(dataIdValue)).append("\n"); sb.append(" simName: ").append(toIndentedString(simName)).append("\n"); - sb.append(" appName: ").append(toIndentedString(appName)).append("\n"); - sb.append(" bioName: ").append(toIndentedString(bioName)).append("\n"); + sb.append(" modelName: ").append(toIndentedString(modelName)).append("\n"); sb.append(" variables: ").append(toIndentedString(variables)).append("\n"); - sb.append(" parameterValues: ").append(toIndentedString(parameterValues)).append("\n"); sb.append(" startTimeValue: ").append(toIndentedString(startTimeValue)).append("\n"); sb.append(" endTimeValue: ").append(toIndentedString(endTimeValue)).append("\n"); sb.append(" savedFileNameValue: ").append(toIndentedString(savedFileNameValue)).append("\n"); - sb.append(" applicationTypeValue: ").append(toIndentedString(applicationTypeValue)).append("\n"); - sb.append(" nonSpatialValue: ").append(toIndentedString(nonSpatialValue)).append("\n"); - sb.append(" zSlicesValue: ").append(toIndentedString(zSlicesValue)).append("\n"); - sb.append(" tSlicesValue: ").append(toIndentedString(tSlicesValue)).append("\n"); - sb.append(" numVariablesValue: ").append(toIndentedString(numVariablesValue)).append("\n"); + sb.append(" selectedZSlice: ").append(toIndentedString(selectedZSlice)).append("\n"); + sb.append(" entireZStack: ").append(toIndentedString(entireZStack)).append("\n"); + sb.append(" eventStatus: ").append(toIndentedString(eventStatus)).append("\n"); sb.append("}"); return sb.toString(); } @@ -717,9 +648,9 @@ public String toUrlQueryString(String prefix) { StringJoiner joiner = new StringJoiner("&"); - // add `jobID` to the URL query string - if (getJobID() != null) { - joiner.add(String.format("%sjobID%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getJobID()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + // add `exportJobID` to the URL query string + if (getExportJobID() != null) { + joiner.add(String.format("%sexportJobID%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getExportJobID()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } // add `simulationRef` to the URL query string @@ -727,6 +658,21 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format("%ssimulationRef%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSimulationRef()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } + // add `bioModelRef` to the URL query string + if (getBioModelRef() != null) { + joiner.add(String.format("%sbioModelRef%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getBioModelRef()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `mathModelRef` to the URL query string + if (getMathModelRef() != null) { + joiner.add(String.format("%smathModelRef%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getMathModelRef()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `mathRef` to the URL query string + if (getMathRef() != null) { + joiner.add(String.format("%smathRef%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getMathRef()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + // add `exportFormat` to the URL query string if (getExportFormat() != null) { joiner.add(String.format("%sexportFormat%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getExportFormat()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); @@ -742,24 +688,14 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format("%suri%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getUri()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } - // add `dataIdValue` to the URL query string - if (getDataIdValue() != null) { - joiner.add(String.format("%sdataIdValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getDataIdValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - // add `simName` to the URL query string if (getSimName() != null) { joiner.add(String.format("%ssimName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSimName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } - // add `appName` to the URL query string - if (getAppName() != null) { - joiner.add(String.format("%sappName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getAppName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - - // add `bioName` to the URL query string - if (getBioName() != null) { - joiner.add(String.format("%sbioName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getBioName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + // add `modelName` to the URL query string + if (getModelName() != null) { + joiner.add(String.format("%smodelName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getModelName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } // add `variables` to the URL query string @@ -771,16 +707,6 @@ public String toUrlQueryString(String prefix) { } } - // add `parameterValues` to the URL query string - if (getParameterValues() != null) { - for (int i = 0; i < getParameterValues().size(); i++) { - if (getParameterValues().get(i) != null) { - joiner.add(getParameterValues().get(i).toUrlQueryString(String.format("%sparameterValues%s%s", prefix, suffix, - "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix)))); - } - } - } - // add `startTimeValue` to the URL query string if (getStartTimeValue() != null) { joiner.add(String.format("%sstartTimeValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getStartTimeValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); @@ -796,29 +722,19 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format("%ssavedFileNameValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSavedFileNameValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } - // add `applicationTypeValue` to the URL query string - if (getApplicationTypeValue() != null) { - joiner.add(String.format("%sapplicationTypeValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getApplicationTypeValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - - // add `nonSpatialValue` to the URL query string - if (getNonSpatialValue() != null) { - joiner.add(String.format("%snonSpatialValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getNonSpatialValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - - // add `zSlicesValue` to the URL query string - if (getzSlicesValue() != null) { - joiner.add(String.format("%szSlicesValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getzSlicesValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + // add `selectedZSlice` to the URL query string + if (getSelectedZSlice() != null) { + joiner.add(String.format("%sselectedZSlice%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSelectedZSlice()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } - // add `tSlicesValue` to the URL query string - if (gettSlicesValue() != null) { - joiner.add(String.format("%stSlicesValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(gettSlicesValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + // add `entireZStack` to the URL query string + if (getEntireZStack() != null) { + joiner.add(String.format("%sentireZStack%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getEntireZStack()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } - // add `numVariablesValue` to the URL query string - if (getNumVariablesValue() != null) { - joiner.add(String.format("%snumVariablesValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getNumVariablesValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + // add `eventStatus` to the URL query string + if (getEventStatus() != null) { + joiner.add(String.format("%seventStatus%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getEventStatus()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } return joiner.toString(); diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/StandardExportInfo.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/StandardExportInfo.java index 33cdf9aa5e..140dbba5bf 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/StandardExportInfo.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/StandardExportInfo.java @@ -45,7 +45,10 @@ StandardExportInfo.JSON_PROPERTY_SIMULATION_JOB, StandardExportInfo.JSON_PROPERTY_GEOMETRY_SPECS, StandardExportInfo.JSON_PROPERTY_TIME_SPECS, - StandardExportInfo.JSON_PROPERTY_VARIABLE_SPECS + StandardExportInfo.JSON_PROPERTY_VARIABLE_SPECS, + StandardExportInfo.JSON_PROPERTY_BIO_MODEL_KEY, + StandardExportInfo.JSON_PROPERTY_MATH_MODEL_KEY, + StandardExportInfo.JSON_PROPERTY_MATH_DESCRIPTION_KEY }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class StandardExportInfo { @@ -73,6 +76,15 @@ public class StandardExportInfo { public static final String JSON_PROPERTY_VARIABLE_SPECS = "variableSpecs"; private VariableSpecs variableSpecs; + public static final String JSON_PROPERTY_BIO_MODEL_KEY = "bioModelKey"; + private String bioModelKey; + + public static final String JSON_PROPERTY_MATH_MODEL_KEY = "mathModelKey"; + private String mathModelKey; + + public static final String JSON_PROPERTY_MATH_DESCRIPTION_KEY = "mathDescriptionKey"; + private String mathDescriptionKey; + public StandardExportInfo() { } @@ -284,6 +296,81 @@ public void setVariableSpecs(VariableSpecs variableSpecs) { } + public StandardExportInfo bioModelKey(String bioModelKey) { + this.bioModelKey = bioModelKey; + return this; + } + + /** + * Get bioModelKey + * @return bioModelKey + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_BIO_MODEL_KEY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getBioModelKey() { + return bioModelKey; + } + + + @JsonProperty(JSON_PROPERTY_BIO_MODEL_KEY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setBioModelKey(String bioModelKey) { + this.bioModelKey = bioModelKey; + } + + + public StandardExportInfo mathModelKey(String mathModelKey) { + this.mathModelKey = mathModelKey; + return this; + } + + /** + * Get mathModelKey + * @return mathModelKey + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_MATH_MODEL_KEY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getMathModelKey() { + return mathModelKey; + } + + + @JsonProperty(JSON_PROPERTY_MATH_MODEL_KEY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMathModelKey(String mathModelKey) { + this.mathModelKey = mathModelKey; + } + + + public StandardExportInfo mathDescriptionKey(String mathDescriptionKey) { + this.mathDescriptionKey = mathDescriptionKey; + return this; + } + + /** + * Get mathDescriptionKey + * @return mathDescriptionKey + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_MATH_DESCRIPTION_KEY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getMathDescriptionKey() { + return mathDescriptionKey; + } + + + @JsonProperty(JSON_PROPERTY_MATH_DESCRIPTION_KEY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMathDescriptionKey(String mathDescriptionKey) { + this.mathDescriptionKey = mathDescriptionKey; + } + + /** * Return true if this StandardExportInfo object is equal to o. */ @@ -303,12 +390,15 @@ public boolean equals(Object o) { Objects.equals(this.simulationJob, standardExportInfo.simulationJob) && Objects.equals(this.geometrySpecs, standardExportInfo.geometrySpecs) && Objects.equals(this.timeSpecs, standardExportInfo.timeSpecs) && - Objects.equals(this.variableSpecs, standardExportInfo.variableSpecs); + Objects.equals(this.variableSpecs, standardExportInfo.variableSpecs) && + Objects.equals(this.bioModelKey, standardExportInfo.bioModelKey) && + Objects.equals(this.mathModelKey, standardExportInfo.mathModelKey) && + Objects.equals(this.mathDescriptionKey, standardExportInfo.mathDescriptionKey); } @Override public int hashCode() { - return Objects.hash(outputContext, contextName, simulationName, simulationKey, simulationJob, geometrySpecs, timeSpecs, variableSpecs); + return Objects.hash(outputContext, contextName, simulationName, simulationKey, simulationJob, geometrySpecs, timeSpecs, variableSpecs, bioModelKey, mathModelKey, mathDescriptionKey); } @Override @@ -323,6 +413,9 @@ public String toString() { sb.append(" geometrySpecs: ").append(toIndentedString(geometrySpecs)).append("\n"); sb.append(" timeSpecs: ").append(toIndentedString(timeSpecs)).append("\n"); sb.append(" variableSpecs: ").append(toIndentedString(variableSpecs)).append("\n"); + sb.append(" bioModelKey: ").append(toIndentedString(bioModelKey)).append("\n"); + sb.append(" mathModelKey: ").append(toIndentedString(mathModelKey)).append("\n"); + sb.append(" mathDescriptionKey: ").append(toIndentedString(mathDescriptionKey)).append("\n"); sb.append("}"); return sb.toString(); } @@ -415,6 +508,21 @@ public String toUrlQueryString(String prefix) { joiner.add(getVariableSpecs().toUrlQueryString(prefix + "variableSpecs" + suffix)); } + // add `bioModelKey` to the URL query string + if (getBioModelKey() != null) { + joiner.add(String.format("%sbioModelKey%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getBioModelKey()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `mathModelKey` to the URL query string + if (getMathModelKey() != null) { + joiner.add(String.format("%smathModelKey%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getMathModelKey()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `mathDescriptionKey` to the URL query string + if (getMathDescriptionKey() != null) { + joiner.add(String.format("%smathDescriptionKey%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getMathDescriptionKey()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + return joiner.toString(); } } diff --git a/webapp-ng/src/app/core/modules/openapi/model/export-history.ts b/webapp-ng/src/app/core/modules/openapi/model/export-history.ts index 6600d427ef..b3f505b2fa 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/export-history.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/export-history.ts @@ -9,30 +9,28 @@ * https://openapi-generator.tech * Do not edit the class manually. */ -import { DifferentParameterValues } from './different-parameter-values'; +import { ExportProgressType } from './export-progress-type'; import { ExportFormat } from './export-format'; export interface ExportHistory { - jobID?: number; + exportJobID?: number; simulationRef?: string; + bioModelRef?: string; + mathModelRef?: string; + mathRef?: string; exportFormat?: ExportFormat; exportDate?: string; uri?: string; - dataIdValue?: string; simName?: string; - appName?: string; - bioName?: string; + modelName?: string; variables?: Array; - parameterValues?: Array; startTimeValue?: number; endTimeValue?: number; savedFileNameValue?: string; - applicationTypeValue?: string; - nonSpatialValue?: boolean; - zSlicesValue?: number; - tSlicesValue?: number; - numVariablesValue?: number; + selectedZSlice?: number; + entireZStack?: boolean; + eventStatus?: ExportProgressType; } export namespace ExportHistory { } diff --git a/webapp-ng/src/app/core/modules/openapi/model/standard-export-info.ts b/webapp-ng/src/app/core/modules/openapi/model/standard-export-info.ts index 868436953c..a8732c9263 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/standard-export-info.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/standard-export-info.ts @@ -24,5 +24,8 @@ export interface StandardExportInfo { geometrySpecs?: GeometrySpecDTO; timeSpecs?: TimeSpecs; variableSpecs?: VariableSpecs; + bioModelKey?: string; + mathModelKey?: string; + mathDescriptionKey?: string; } From 2a7048a0eb3ea66ea0a2cde6433714008288fbb1 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 6 Apr 2026 10:29:06 -0400 Subject: [PATCH 55/65] Test New Export History Client --- .../src/main/resources/scripts/init.sql | 2 +- .../org/vcell/restq/TestEndpointUtils.java | 1 + .../org/vcell/restq/exports/ExportHelper.java | 14 ++- .../exports/ExportHistoryClientTest.java | 88 +++++++++++++++++++ .../restq/exports/ExportRequestTest.java | 8 +- 5 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 17795fc210..b937800941 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -93,7 +93,7 @@ CREATE TABLE vc_simulation_export_history ( end_time numeric NOT NULL, entire_z_stack numeric NOT NULL, z_slice numeric, - saved_file_name varchar(50) NOT NULL, + saved_file_name varchar(50), event_status varchar(50) NOT NULL ); diff --git a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java index aa73b22739..5db28bc190 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -186,6 +186,7 @@ public static DataServerImpl createDataServerImpl() throws FileNotFoundException public static void clearAllBioModelEntries(AgroalConnectionFactory agroalConnectionFactory) throws DataAccessException, SQLException { Object object = new Object(); Connection connection = agroalConnectionFactory.getConnection(object); + connection.prepareStatement("DELETE FROM VC_SIMULATION_EXPORT_HISTORY").execute(); connection.prepareStatement("DELETE FROM VC_BIOMODEL").execute(); connection.prepareStatement("DELETE FROM VC_BIOMODELXML").execute(); connection.prepareStatement("DELETE FROM VC_BIOMODELSIM").execute(); diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java index 7e49061c48..10aa3b1d8e 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHelper.java @@ -1,6 +1,9 @@ package org.vcell.restq.exports; +import cbit.vcell.biomodel.BioModel; import cbit.vcell.export.server.ExportEnums; +import cbit.vcell.exports.ExportHistory; +import cbit.vcell.exports.ExportHistoryDBRep; import cbit.vcell.math.VariableType; import cbit.vcell.simdata.*; import cbit.vcell.simdata.DataIdentifier; @@ -70,16 +73,16 @@ private static ExportEvent getLastEventForJob(List events, long job } public static N5ExportRequest getValidExportRequestDTO(int startTimeIndex, int endTimeIndex, - DataServerImpl dataServer, String simulationID) throws Exception { - VCSimulationIdentifier vcSimulationIdentifier = new VCSimulationIdentifier(new KeyValue(simulationID), TestEndpointUtils.administratorUser); + DataServerImpl dataServer, Simulation simulationID, BioModel bioModel) throws Exception { + VCSimulationIdentifier vcSimulationIdentifier = new VCSimulationIdentifier(simulationID.getKey(), TestEndpointUtils.administratorUser); VCSimulationDataIdentifier simulationDataIdentifier = new VCSimulationDataIdentifier(vcSimulationIdentifier, 0); DataIdentifier[] dataIdentifier = dataServer.getDataIdentifiers(new OutputContext(new AnnotatedFunction[0]), TestEndpointUtils.administratorUser, simulationDataIdentifier); DataIdentifier volumetricDataID = getOneDIWithSpecificType(VariableType.VOLUME, dataIdentifier); double[] allTimes = dataServer.getDataSetTimes(TestEndpointUtils.administratorUser, simulationDataIdentifier); StandardExportInfo exportRequest = new StandardExportInfo() - .simulationKey(simulationID) + .simulationKey(simulationID.getVersion().getVersionKey().toString()) .simulationJob(0) - .geometrySpecs(new GeometrySpecDTO().geometryMode(GeometryMode.SELECTIONS).selections(new ArrayList<>())) + .geometrySpecs(new GeometrySpecDTO().geometryMode(GeometryMode.FULL)) .timeSpecs( new org.vcell.restclient.model.TimeSpecs().beginTimeIndex(startTimeIndex).endTimeIndex(endTimeIndex).allTimes(Arrays.stream(allTimes).boxed().toList()).mode(TimeMode.RANGE) ) @@ -88,6 +91,9 @@ public static N5ExportRequest getValidExportRequestDTO(int startTimeIndex, int e ) .contextName("") .simulationName(vcSimulationIdentifier.getID()) + .bioModelKey(bioModel.getVersion().getVersionKey().toString()) + .mathModelKey(null) + .mathDescriptionKey(bioModel.getSimulationContext(0).getMathDescription().getVersion().getVersionKey().toString()) .outputContext(new ArrayList<>()); return new N5ExportRequest().standardExportInformation(exportRequest) diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java new file mode 100644 index 0000000000..cc219fee83 --- /dev/null +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java @@ -0,0 +1,88 @@ +package org.vcell.restq.exports; + +import cbit.vcell.biomodel.BioModel; +import cbit.vcell.modeldb.DatabaseServerImpl; +import cbit.vcell.resource.PropertyLoader; +import cbit.vcell.simdata.DataServerImpl; +import cbit.vcell.xml.XmlParseException; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.keycloak.client.KeycloakTestClient; +import jakarta.inject.Inject; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.junit.jupiter.api.*; +import org.vcell.restclient.ApiClient; +import org.vcell.restclient.ApiException; +import org.vcell.restclient.api.ExportResourceApi; +import org.vcell.restclient.model.*; +import org.vcell.restq.TestEndpointUtils; +import org.vcell.restq.config.CDIVCellConfigProvider; +import org.vcell.restq.db.AgroalConnectionFactory; +import org.vcell.util.DataAccessException; + +import java.beans.PropertyVetoException; +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +@QuarkusTest +public class ExportHistoryClientTest { + @ConfigProperty(name = "quarkus.http.test-port") + Integer testPort; + @Inject + AgroalConnectionFactory agroalConnectionFactory; + + private static final Logger lg = LogManager.getLogger(ExportHistoryClientTest.class); + + KeycloakTestClient keycloakClient = new KeycloakTestClient(); + + private DataServerImpl dataServer; + private final String simulationID = "597714292"; + private BioModel frapModel; + private ApiClient aliceAPIClient; + + @BeforeAll + public static void setupConfig(){ + PropertyLoader.setConfigProvider(new CDIVCellConfigProvider()); + } + + @BeforeEach + public void setUp() throws IOException, DataAccessException, ApiException, SQLException, PropertyVetoException, XmlParseException { + aliceAPIClient = TestEndpointUtils.createAuthenticatedAPIClient(keycloakClient, testPort, TestEndpointUtils.TestOIDCUsers.alice); + TestEndpointUtils.mapApiClientToAdmin(aliceAPIClient); + + dataServer = TestEndpointUtils.createDataServerImpl(); + frapModel = TestEndpointUtils.insertFrapModel(agroalConnectionFactory); + } + + @AfterEach + public void removeOIDCMappings() throws SQLException, DataAccessException { + TestEndpointUtils.clearAllBioModelEntries(agroalConnectionFactory); + TestEndpointUtils.restoreSystemProperties(); + } + +// Tests the clients capability to submit exports, our queue for accepting and distributing messages, retrieval of export status, and the export job itself + @Test + public void testExportRequestClient() throws Exception { + ExportResourceApi exportResourceApi = new ExportResourceApi(aliceAPIClient); + N5ExportRequest exportRequest = ExportHelper.getValidExportRequestDTO(0, 1, dataServer, + frapModel.getSimulation(0), frapModel); + ExportEvent completedExport = ExportHelper.exportAndWait(exportResourceApi, exportRequest); + List exportHistories = exportResourceApi.getExportHistory(); + Assertions.assertFalse(exportHistories.isEmpty()); + Assertions.assertEquals(exportHistories.size(), 1); + Assertions.assertTrue(requestEqualHistory(exportRequest, exportHistories.get(0))); + } + + private boolean requestEqualHistory(N5ExportRequest request, ExportHistory history){ + List allTimes = request.getStandardExportInformation().getTimeSpecs().getAllTimes(); + boolean modelEqual = request.getStandardExportInformation().getBioModelKey().equals(history.getBioModelRef()); + boolean simEqual = request.getStandardExportInformation().getSimulationKey().equals(history.getSimulationRef()); + boolean startTimeEqual = allTimes.get(request.getStandardExportInformation().getTimeSpecs().getBeginTimeIndex()).equals(history.getStartTimeValue()); + boolean endTimeEqual = allTimes.get(request.getStandardExportInformation().getTimeSpecs().getEndTimeIndex()).equals(history.getEndTimeValue()); + boolean exportComplete = history.getEventStatus().equals(ExportProgressType.COMPLETE); + boolean correctFormat = history.getExportFormat().equals(ExportFormat.N5); + return modelEqual && simEqual && startTimeEqual && endTimeEqual && exportComplete && correctFormat; + } +} diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java index 3d85df4a46..60cc67a0aa 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportRequestTest.java @@ -1,5 +1,6 @@ package org.vcell.restq.exports; +import cbit.vcell.biomodel.BioModel; import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.resource.PropertyLoader; import cbit.vcell.simdata.*; @@ -34,8 +35,8 @@ public class ExportRequestTest { KeycloakTestClient keycloakClient = new KeycloakTestClient(); private DataServerImpl dataServer; - private final String simulationID = "597714292"; private ApiClient aliceAPIClient; + private BioModel frapModel; @BeforeAll public static void setupConfig(){ @@ -47,7 +48,7 @@ public void setUp() throws IOException, DataAccessException, ApiException, SQLEx aliceAPIClient = TestEndpointUtils.createAuthenticatedAPIClient(keycloakClient, testPort, TestEndpointUtils.TestOIDCUsers.alice); TestEndpointUtils.mapApiClientToAdmin(aliceAPIClient); dataServer = TestEndpointUtils.createDataServerImpl(); - TestEndpointUtils.insertFrapModel(agroalConnectionFactory); + frapModel = TestEndpointUtils.insertFrapModel(agroalConnectionFactory); } @AfterEach @@ -60,7 +61,8 @@ public void removeOIDCMappings() throws SQLException, DataAccessException { @Test public void testExportRequestClient() throws Exception { ExportResourceApi exportResourceApi = new ExportResourceApi(aliceAPIClient); - N5ExportRequest exportRequest = getValidExportRequestDTO(0, 1, dataServer, simulationID); + N5ExportRequest exportRequest = getValidExportRequestDTO(0, 1, dataServer, + frapModel.getSimulation(0), frapModel); ExportHelper.exportAndWait(exportResourceApi, exportRequest); } From 11adde82632437868cc77c589faa1202d6a5065f Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 6 Apr 2026 11:09:26 -0400 Subject: [PATCH 56/65] Test JobID And Names --- .../restq/services/Exports/ServerExportEventController.java | 2 +- .../org/vcell/restq/exports/ExportHistoryClientTest.java | 6 +++++- .../main/java/cbit/vcell/exports/ExportHistoryDBDriver.java | 5 +---- .../main/java/cbit/vcell/exports/ExportHistoryDBRep.java | 4 ++-- .../main/java/cbit/vcell/exports/ExportHistoryTable.java | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java index e65ff5d43c..8cc4faae22 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ServerExportEventController.java @@ -154,7 +154,7 @@ public synchronized ExportEvent fireExportCompleted(long jobID, VCDataIdentifier if (exportSpecs != null && exportSpecs.getVCDataIdentifier() instanceof VCSimulationDataIdentifier vcSimulationDataIdentifier){ try{ - databaseServerImpl.addExportHistory(user, ExportHistoryDBRep.fromExportSpec(exportSpecs, location, (int) jobID, vcSimulationDataIdentifier, ExportEnums.ExportProgressType.EXPORT_COMPLETE)); + databaseServerImpl.addExportHistory(user, ExportHistoryDBRep.fromExportSpec(exportSpecs, location, jobID, vcSimulationDataIdentifier, ExportEnums.ExportProgressType.EXPORT_COMPLETE)); } catch (DataAccessException e) { logger.error("Couldn't add export history to database for user " + user.getName() + ", job id " + jobID + ", and export spec " + exportSpecs, e); diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java index cc219fee83..232722e920 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java @@ -72,6 +72,9 @@ public void testExportRequestClient() throws Exception { List exportHistories = exportResourceApi.getExportHistory(); Assertions.assertFalse(exportHistories.isEmpty()); Assertions.assertEquals(exportHistories.size(), 1); + Assertions.assertEquals(exportHistories.get(0).getExportJobID(), completedExport.getJobID()); + Assertions.assertEquals(exportHistories.get(0).getSimName(), frapModel.getSimulation(0).getName()); + Assertions.assertEquals(exportHistories.get(0).getModelName(), frapModel.getName()); Assertions.assertTrue(requestEqualHistory(exportRequest, exportHistories.get(0))); } @@ -83,6 +86,7 @@ private boolean requestEqualHistory(N5ExportRequest request, ExportHistory histo boolean endTimeEqual = allTimes.get(request.getStandardExportInformation().getTimeSpecs().getEndTimeIndex()).equals(history.getEndTimeValue()); boolean exportComplete = history.getEventStatus().equals(ExportProgressType.COMPLETE); boolean correctFormat = history.getExportFormat().equals(ExportFormat.N5); - return modelEqual && simEqual && startTimeEqual && endTimeEqual && exportComplete && correctFormat; + boolean variablesEqual = List.of(request.getStandardExportInformation().getVariableSpecs().getVariableNames()).equals(List.of(history.getVariables())); + return modelEqual && simEqual && startTimeEqual && endTimeEqual && exportComplete && correctFormat && variablesEqual; } } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java index 028e1565d2..b5afbbd760 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java @@ -57,10 +57,7 @@ public void addExportHistory(Connection conn, User user, ExportHistoryDBRep expo exportHistory.savedFileNameValue(), exportHistory.eventStatus().toString() ); - System.out.println("Data insertion tag:"); - System.out.println(ps.executeUpdate()); - System.out.println("."); - //ps.executeUpdate(); + ps.executeUpdate(); } } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java index 070dacffed..42cf6b2757 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java @@ -12,7 +12,7 @@ import java.util.List; public record ExportHistoryDBRep( - int jobID, + long jobID, KeyValue bioModelRef, KeyValue mathModelRef, KeyValue simulationRef, @@ -49,7 +49,7 @@ public static ExportHistoryDBRep fromExportSpec(ExportSpecs exportSpecs, String double[] times = exportSpecs.getTimeSpecs().getAllTimes(); boolean entireZStack = exportSpecs.getGeometrySpecs().getMode() == ExportEnums.GeometryMode.GEOMETRY_FULL; return new ExportHistoryDBRep( - (int) jobID, + jobID, exportSpecs.getBioModelKey(), exportSpecs.getMathModelKey(), simDataId.getSimulationKey(), diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java index b7049e3acb..958e7d9ce2 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java @@ -81,7 +81,7 @@ public String getInsertSQL() { public void bindForInsert( PreparedStatement ps, KeyValue keyValue, - int jobIdValue, + long jobIdValue, int userRefValue, Integer bioModelRef, Integer mathModelRef, @@ -133,7 +133,7 @@ public ExportHistory getExportHistoryRecord(ResultSet rset) throws SQLException, Timestamp date = rset.getTimestamp(this.exportDate.getUnqualifiedColName()); // strings - int jobId = rset.getInt(this.jobId.getUnqualifiedColName()); + long jobId = rset.getLong(this.jobId.getUnqualifiedColName()); String uriVal = rset.getString(this.uri.getUnqualifiedColName()); String simNameVal = rset.getString("sim_name"); String mathModelNameVal = rset.getString("math_model_name"); From 1b163771978b1edd39d7edf248e250d760e04cfa Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 6 Apr 2026 14:20:31 -0400 Subject: [PATCH 57/65] Remove Geometry and File Name Column --- vcell-rest/src/main/resources/scripts/init.sql | 2 -- .../restq/exports/ExportHistoryDBTest.java | 14 ++------------ .../java/cbit/vcell/exports/ExportHistory.java | 3 --- .../vcell/exports/ExportHistoryDBDriver.java | 5 ----- .../cbit/vcell/exports/ExportHistoryDBRep.java | 13 +------------ .../cbit/vcell/exports/ExportHistoryTable.java | 17 ++--------------- 6 files changed, 5 insertions(+), 49 deletions(-) diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index b937800941..32bbc0746a 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -91,8 +91,6 @@ CREATE TABLE vc_simulation_export_history ( variables text[] NOT NULL, start_time numeric NOT NULL, end_time numeric NOT NULL, - entire_z_stack numeric NOT NULL, - z_slice numeric, saved_file_name varchar(50), event_status varchar(50) NOT NULL ); diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index de4ac5f666..fbca89fe84 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -3,18 +3,13 @@ import cbit.vcell.biomodel.BioModel; import cbit.vcell.export.server.*; import cbit.vcell.exports.ExportHistory; -import cbit.vcell.math.Constant; -import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.exports.ExportHistoryDBDriver; import cbit.vcell.exports.ExportHistoryDBRep; -import cbit.vcell.parser.Expression; import cbit.vcell.parser.ExpressionException; import cbit.vcell.resource.PropertyLoader; import cbit.vcell.solver.Simulation; import cbit.vcell.solver.VCSimulationDataIdentifier; import cbit.vcell.solver.VCSimulationIdentifier; -import cbit.vcell.xml.XMLSource; -import cbit.vcell.xml.XmlHelper; import cbit.vcell.xml.XmlParseException; import com.fasterxml.jackson.core.JsonProcessingException; import io.quarkus.test.junit.QuarkusTest; @@ -23,7 +18,6 @@ import org.vcell.restq.TestEndpointUtils; import org.vcell.restq.config.CDIVCellConfigProvider; import org.vcell.restq.db.AgroalConnectionFactory; -import org.vcell.util.BigString; import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; @@ -83,8 +77,7 @@ private ExportHistoryDBRep getExportHistoryRep(int jobID, String uri, Timestamp jobID, savedBioModel.getVersion().getVersionKey(), null, savedSimulation.getKey(), savedSimulation.getMathDescription().getKey(), ExportFormat.N5, timestamp, uri, variableSpecs.getVariableNames(), - 1.2, 3.4, false, 1, - "nameOnServer", ExportEnums.ExportProgressType.EXPORT_COMPLETE + 1.2, 3.4, ExportEnums.ExportProgressType.EXPORT_COMPLETE ); } @@ -196,9 +189,6 @@ private boolean historyDBEqualHistory(ExportHistoryDBRep dbRep, ExportHistory hi List.of(dbRep.variables()).equals(List.of(history.variables())) && Double.compare(dbRep.startTimeValue(), history.startTimeValue()) == 0 && Double.compare(dbRep.endTimeValue(), history.endTimeValue()) == 0 && - dbRep.savedFileNameValue().equals(history.savedFileNameValue()) && - dbRep.eventStatus().toString().equals(history.eventStatus().toString()) && - dbRep.selectedZSlice() == history.selectedZSlice() && - dbRep.entireZStack() == history.entireZStack(); + dbRep.eventStatus().toString().equals(history.eventStatus().toString()); } } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java index 87fea31cf7..7aa2227664 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistory.java @@ -22,10 +22,7 @@ public record ExportHistory( // List overrides, double startTimeValue, double endTimeValue, - String savedFileNameValue, // String applicationTypeValue, - int selectedZSlice, - boolean entireZStack, ExportEnums.ExportProgressType eventStatus ) { } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java index b5afbbd760..04053feb9a 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java @@ -1,8 +1,6 @@ package cbit.vcell.exports; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.postgresql.util.PGobject; import org.vcell.db.DatabaseSyntax; import org.vcell.db.KeyFactory; import org.vcell.util.DataAccessException; @@ -52,9 +50,6 @@ public void addExportHistory(Connection conn, User user, ExportHistoryDBRep expo conn.createArrayOf("VARCHAR", exportHistory.variables()), exportHistory.startTimeValue(), exportHistory.endTimeValue(), - exportHistory.entireZStack(), - exportHistory.selectedZSlice(), - exportHistory.savedFileNameValue(), exportHistory.eventStatus().toString() ); ps.executeUpdate(); diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java index 42cf6b2757..156460bafe 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBRep.java @@ -3,7 +3,6 @@ import cbit.vcell.export.server.ExportEnums; import cbit.vcell.export.server.ExportFormat; import cbit.vcell.export.server.ExportSpecs; -import cbit.vcell.export.server.HumanReadableExportData; import cbit.vcell.solver.VCSimulationDataIdentifier; import org.vcell.util.document.KeyValue; @@ -23,9 +22,6 @@ public record ExportHistoryDBRep( String[] variables, double startTimeValue, double endTimeValue, - boolean entireZStack, - int selectedZSlice, - String savedFileNameValue, ExportEnums.ExportProgressType eventStatus ) { public boolean equals(ExportHistoryDBRep other){ @@ -39,15 +35,11 @@ public boolean equals(ExportHistoryDBRep other){ List.of(this.variables).equals(List.of(other.variables)) && Double.compare(this.startTimeValue, other.startTimeValue) == 0 && Double.compare(this.endTimeValue, other.endTimeValue) == 0 && - this.savedFileNameValue.equals(other.savedFileNameValue) && - this.eventStatus.equals(other.eventStatus) && - this.entireZStack == other.entireZStack && - this.selectedZSlice == other.selectedZSlice; + this.eventStatus.equals(other.eventStatus); } public static ExportHistoryDBRep fromExportSpec(ExportSpecs exportSpecs, String url, long jobID, VCSimulationDataIdentifier simDataId, ExportEnums.ExportProgressType eventStatus) { double[] times = exportSpecs.getTimeSpecs().getAllTimes(); - boolean entireZStack = exportSpecs.getGeometrySpecs().getMode() == ExportEnums.GeometryMode.GEOMETRY_FULL; return new ExportHistoryDBRep( jobID, exportSpecs.getBioModelKey(), @@ -60,9 +52,6 @@ public static ExportHistoryDBRep fromExportSpec(ExportSpecs exportSpecs, String exportSpecs.getVariableSpecs().getVariableNames(), times[exportSpecs.getTimeSpecs().getBeginTimeIndex()], times[exportSpecs.getTimeSpecs().getEndTimeIndex()], - entireZStack, - entireZStack ? exportSpecs.getGeometrySpecs().getSliceNumber() : -1, - null, eventStatus ); } diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java index 958e7d9ce2..1d075650a6 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java @@ -34,9 +34,6 @@ public class ExportHistoryTable extends Table { public final Field variables = new Field("variables", Field.SQLDataType.varchar_255, "[] NOT NULL"); public final Field startTime = new Field("start_time", Field.SQLDataType.number_as_real, "NOT NULL"); public final Field endTime = new Field("end_time", Field.SQLDataType.number_as_real, "NOT NULL"); - public final Field entireZStack = new Field("entire_z_stack", Field.SQLDataType.integer, "NOT NULL CHECK (entire_z_stack IN (0,1))"); - public final Field selectedZSliceInStack = new Field("z_slice", Field.SQLDataType.integer, ""); - public final Field savedFileName = new Field("saved_file_name", Field.SQLDataType.varchar_50, ""); public final Field eventStatus = new Field("event_status", Field.SQLDataType.varchar_50, "NOT NULL"); @@ -58,7 +55,7 @@ private ExportHistoryTable() { // note that primary key id cannot be placed in fields (will causes class initialization error), jobId, userRef, bioModelRef, mathModelRef, simulationRef, mathRef, exportFormat, exportDate, uri, variables, - startTime, endTime, entireZStack, selectedZSliceInStack, savedFileName, eventStatus + startTime, endTime, eventStatus }; addFields(customFields); } @@ -93,9 +90,6 @@ public void bindForInsert( Array variables, double startTimeValue, double endTimeValue, - boolean entireZStack, - int selectedZSlice, - String savedFileNameValue, String eventStatusValue ) throws SQLException { int i = 1; @@ -116,9 +110,6 @@ public void bindForInsert( ps.setArray (i++, variables); ps.setDouble (i++, startTimeValue); ps.setDouble (i++, endTimeValue); - ps.setInt (i++, entireZStack ? 1 : 0); - ps.setInt (i++, selectedZSlice); - ps.setString (i++, savedFileNameValue); ps.setString (i++, eventStatusValue); } @@ -145,11 +136,8 @@ public ExportHistory getExportHistoryRecord(ResultSet rset) throws SQLException, // numeric ranges double startBt = rset.getDouble(this.startTime.getUnqualifiedColName()); double endBt = rset.getDouble(this.endTime.getUnqualifiedColName()); - int zS = rset.getInt(this.selectedZSliceInStack.getUnqualifiedColName()); - int ez = rset.getInt(this.entireZStack.getUnqualifiedColName()); // more strings & flags - String savedFileVal = rset.getString(this.savedFileName.getUnqualifiedColName()); String eventStatusVal = rset.getString(this.eventStatus.getUnqualifiedColName()); @@ -167,8 +155,7 @@ public ExportHistory getExportHistoryRecord(ResultSet rset) throws SQLException, jobId, new KeyValue("" + simulationRef), bioModelRef == null ? null : new KeyValue("" + bioModelRef), mathModelRef == null ? null : new KeyValue("" + mathModelRef), new KeyValue("" + mathRef), fmt, date.toInstant(), uriVal, simNameVal, modelName, variables, - startBt, endBt, savedFileVal, - zS, ez == 1, ExportEnums.ExportProgressType.valueOf(eventStatusVal) + startBt, endBt, ExportEnums.ExportProgressType.valueOf(eventStatusVal) ); } } From e0dac7a30d01d504384163120759971f4ac2bcd6 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 7 Apr 2026 10:32:12 -0400 Subject: [PATCH 58/65] Generate Proper SQL Init Script --- .../src/main/resources/scripts/init.sql | 20 +------------------ .../vcell/exports/ExportHistoryTable.java | 20 +++++++++---------- .../vcell/modeldb/SQLCreateAllTables.java | 6 ++++++ 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 32bbc0746a..97877c86a7 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -76,25 +76,7 @@ CREATE TABLE vc_userlogininfo(id bigint PRIMARY KEY,userRef bigint NOT NULL REFE CREATE TABLE vc_metadata(id bigint PRIMARY KEY,bioModelRef bigint NOT NULL REFERENCES vc_biomodel(id) ON DELETE CASCADE,vcMetaDataLarge text ,vcMetaDataSmall varchar(4000) ); CREATE TABLE vc_simdelfromdisk(deldate varchar(20) ,userid varchar(255) NOT NULL,userkey bigint ,simid bigint ,simpref bigint ,simdate varchar(20) ,simname varchar(255) NOT NULL,status varchar(10) ,numfiles bigint ,totalsize bigint ); CREATE TABLE vc_useridentity(id bigint PRIMARY KEY,userRef bigint NOT NULL REFERENCES vc_userinfo(id),authSubject varchar(128) NOT NULL,authIssuer varchar(128) NOT NULL,insertDate timestamp NOT NULL); - -CREATE TABLE vc_simulation_export_history ( - id bigint PRIMARY KEY, - job_id bigint NOT NULL, - user_ref bigint NOT NULL REFERENCES vc_userinfo(id), - simulation_ref bigint NOT NULL REFERENCES vc_simulation(id), - biomodel_ref bigint REFERENCES vc_biomodel(id), - mathmodel_ref bigint REFERENCES vc_mathmodel(id), - math_ref bigint NOT NULL REFERENCES vc_math(id), - export_format varchar(50) NOT NULL, - export_date timestamp NOT NULL, - uri text NOT NULL, - variables text[] NOT NULL, - start_time numeric NOT NULL, - end_time numeric NOT NULL, - saved_file_name varchar(50), - event_status varchar(50) NOT NULL -); - +CREATE TABLE vc_simulation_export_history(id bigint PRIMARY KEY,job_id bigint NOT NULL,user_ref bigint NOT NULL REFERENCES vc_userinfo(id),biomodel_ref bigint REFERENCES vc_biomodel(id),mathmodel_ref bigint REFERENCES vc_mathmodel(id),simulation_ref bigint NOT NULL REFERENCES vc_simulation(id),math_ref bigint NOT NULL REFERENCES vc_math(id),export_format varchar(50) NOT NULL,export_date timestamp NOT NULL,uri varchar(1024) NOT NULL,variables varchar(4000) [] NOT NULL,start_time numeric NOT NULL,end_time numeric NOT NULL,event_status varchar(50) NOT NULL); CREATE VIEW public.dual AS SELECT CAST('X' as varchar) AS dummy; diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java index 1d075650a6..f3cb77da84 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java @@ -4,9 +4,7 @@ import cbit.sql.Table; import cbit.vcell.export.server.ExportEnums; import cbit.vcell.export.server.ExportFormat; -import cbit.vcell.modeldb.BioModelTable; -import cbit.vcell.modeldb.SimulationTable; -import cbit.vcell.modeldb.UserTable; +import cbit.vcell.modeldb.*; import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; @@ -18,20 +16,20 @@ public class ExportHistoryTable extends Table { // public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); - public final Field jobId = new Field("job_id", Field.SQLDataType.varchar_50, "NOT NULL"); + public final Field jobId = new Field("job_id", Field.SQLDataType.integer, "NOT NULL"); - public final Field userRef = new Field("user_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + UserTable.REF_TYPE); - public final Field bioModelRef = new Field("biomodel_ref", Field.SQLDataType.integer, "REFERENCES" + BioModelTable.REF_TYPE); - public final Field mathModelRef = new Field("mathmodel_ref", Field.SQLDataType.integer, "REFERENCES" + SimulationTable.REF_TYPE); - public final Field simulationRef = new Field("simulation_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + SimulationTable.REF_TYPE); - public final Field mathRef = new Field("math_ref", Field.SQLDataType.integer, "NOT NULL REFERENCES" + SimulationTable.REF_TYPE); + public final Field userRef = new Field("user_ref", Field.SQLDataType.integer, "NOT NULL " + UserTable.REF_TYPE); + public final Field bioModelRef = new Field("biomodel_ref", Field.SQLDataType.integer, BioModelTable.REF_TYPE); + public final Field mathModelRef = new Field("mathmodel_ref", Field.SQLDataType.integer, MathModelTable.REF_TYPE); + public final Field simulationRef = new Field("simulation_ref", Field.SQLDataType.integer, "NOT NULL " + SimulationTable.REF_TYPE); + public final Field mathRef = new Field("math_ref", Field.SQLDataType.integer, "NOT NULL " + MathDescTable.REF_TYPE); public final Field exportFormat = new Field("export_format", Field.SQLDataType.varchar_50, "NOT NULL"); public final Field exportDate = new Field("export_date", Field.SQLDataType.date, "NOT NULL"); - public final Field uri = new Field("uri", Field.SQLDataType.varchar2_4000, "NOT NULL"); + public final Field uri = new Field("uri", Field.SQLDataType.varchar_1024, "NOT NULL"); - public final Field variables = new Field("variables", Field.SQLDataType.varchar_255, "[] NOT NULL"); + public final Field variables = new Field("variables", Field.SQLDataType.varchar2_4000, "[] NOT NULL"); public final Field startTime = new Field("start_time", Field.SQLDataType.number_as_real, "NOT NULL"); public final Field endTime = new Field("end_time", Field.SQLDataType.number_as_real, "NOT NULL"); public final Field eventStatus = new Field("event_status", Field.SQLDataType.varchar_50, "NOT NULL"); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/SQLCreateAllTables.java b/vcell-server/src/main/java/cbit/vcell/modeldb/SQLCreateAllTables.java index 58eb9648ee..e4ed9506ec 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/SQLCreateAllTables.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/SQLCreateAllTables.java @@ -12,6 +12,7 @@ import cbit.sql.Field; import cbit.sql.Table; +import cbit.vcell.exports.ExportHistoryTable; import cbit.vcell.resource.PropertyLoader; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -205,6 +206,8 @@ private static void destroyAndRecreateTables(ConnectionFactory conFactory, KeyFa createIndex(con,"geom_imageref",cbit.vcell.modeldb.GeometryTable.table,cbit.vcell.modeldb.GeometryTable.table.imageRef, dbSyntax); createIndex(con,"mathdesc_geomref",cbit.vcell.modeldb.MathDescTable.table,cbit.vcell.modeldb.MathDescTable.table.geometryRef, dbSyntax); createIndex(con,"simcstat_simcref",cbit.vcell.modeldb.SimContextStatTable.table,cbit.vcell.modeldb.SimContextStatTable.table.simContextRef, dbSyntax); + createIndex(con, "export_history_time", ExportHistoryTable.table, ExportHistoryTable.table.exportDate, dbSyntax); + createIndex(con, "export_history_userref", ExportHistoryTable.table, ExportHistoryTable.table.userRef, dbSyntax); } con.commit(); } catch (SQLException exc) { @@ -376,6 +379,7 @@ public static Table[] getVCellTables() { cbit.vcell.modeldb.VCMetaDataTable.table, // new cbit.vcell.modeldb.SimDelFromDiskTable.table, // new UserIdentityTable.table, + ExportHistoryTable.table // new }; return tables; } @@ -402,6 +406,8 @@ public static void writeScript(DatabaseSyntax dbSyntax, boolean bootstrapData, W scriptWriter.write(getCreateIndexSQL("geom_imageref", GeometryTable.table, GeometryTable.table.imageRef) + ";\n"); scriptWriter.write(getCreateIndexSQL("mathdesc_geomref", MathDescTable.table, MathDescTable.table.geometryRef) + ";\n"); scriptWriter.write(getCreateIndexSQL("simcstat_simcref", SimContextStatTable.table, SimContextStatTable.table.simContextRef) + ";\n"); + scriptWriter.write(getCreateIndexSQL("export_history_userref", ExportHistoryTable.table, ExportHistoryTable.table.userRef) + ";\n"); + scriptWriter.write(getCreateIndexSQL("export_history_time", ExportHistoryTable.table, ExportHistoryTable.table.exportDate) + ";\n"); scriptWriter.write("\n"); if (bootstrapData) { KeyFactory bootstrapKeyFactory = new KeyFactory() { From a3a7ade5e6539ddd80e0e9bd132f548fefba47f4 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 7 Apr 2026 10:33:43 -0400 Subject: [PATCH 59/65] Order by Time --- .../exports/ExportHistoryClientTest.java | 20 ++++++++++++++++++- .../vcell/exports/ExportHistoryDBDriver.java | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java index 232722e920..27c0a1ede4 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java @@ -1,7 +1,6 @@ package org.vcell.restq.exports; import cbit.vcell.biomodel.BioModel; -import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.resource.PropertyLoader; import cbit.vcell.simdata.DataServerImpl; import cbit.vcell.xml.XmlParseException; @@ -78,6 +77,25 @@ public void testExportRequestClient() throws Exception { Assertions.assertTrue(requestEqualHistory(exportRequest, exportHistories.get(0))); } + @Test + public void testExportHistorySequence() throws Exception { + ExportResourceApi exportResourceApi = new ExportResourceApi(aliceAPIClient); + N5ExportRequest exportRequest = ExportHelper.getValidExportRequestDTO(0, 1, dataServer, + frapModel.getSimulation(0), frapModel); + N5ExportRequest exportRequest2 = ExportHelper.getValidExportRequestDTO(2, 4, dataServer, + frapModel.getSimulation(0), frapModel); + ExportEvent completedExport1 = ExportHelper.exportAndWait(exportResourceApi, exportRequest); + ExportEvent completedExport2 = ExportHelper.exportAndWait(exportResourceApi, exportRequest2); + List exportHistories = exportResourceApi.getExportHistory(); + + Assertions.assertFalse(exportHistories.isEmpty()); + Assertions.assertEquals(exportHistories.size(), 2); + Assertions.assertTrue(requestEqualHistory(exportRequest, exportHistories.get(1))); + Assertions.assertTrue(requestEqualHistory(exportRequest2, exportHistories.get(0))); + + Assertions.assertTrue(exportHistories.get(0).getExportDate().isAfter(exportHistories.get(1).getExportDate())); + } + private boolean requestEqualHistory(N5ExportRequest request, ExportHistory history){ List allTimes = request.getStandardExportInformation().getTimeSpecs().getAllTimes(); boolean modelEqual = request.getStandardExportInformation().getBioModelKey().equals(history.getBioModelRef()); diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java index 04053feb9a..a313ccfdba 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java @@ -76,7 +76,7 @@ public List getExportHistoryForUser(Connection conn, User user) t LEFT JOIN vc_biomodel bio ON bio.id = eh.biomodel_ref LEFT JOIN vc_mathmodel math ON math.id = eh.mathmodel_ref LEFT JOIN vc_simcontext simContext ON simContext.mathRef = eh.math_ref - WHERE user_ref = ? + WHERE user_ref = ? ORDER BY export_date DESC """; PreparedStatement ps = conn.prepareStatement(sql); ps.setLong(1, Long.parseLong(user.getID().toString())); From 035012e4e91c043485937d0155e5e73605d91539 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 7 Apr 2026 11:50:33 -0400 Subject: [PATCH 60/65] Paging of Export History Query --- .../main/java/org/vcell/restq/handlers/ExportResource.java | 5 +++-- .../org/vcell/restq/services/Exports/ExportService.java | 4 ++-- .../main/java/cbit/vcell/exports/ExportHistoryDBDriver.java | 5 ++++- .../src/main/java/cbit/vcell/modeldb/DBTopLevel.java | 6 +++--- .../main/java/cbit/vcell/modeldb/DatabaseServerImpl.java | 4 ++-- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java index 75be121068..5a9e75f72d 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java +++ b/vcell-rest/src/main/java/org/vcell/restq/handlers/ExportResource.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; @Path("/api/v1/export") public class ExportResource { @@ -52,10 +53,10 @@ public class ExportResource { @GET @RolesAllowed("user") @Operation(operationId = "getExportHistory") - public List getExportHistory() throws DataAccessWebException, NotAuthenticatedWebException { + public List getExportHistory(@QueryParam("pageNumber") @DefaultValue("0") Optional pageNumber) throws DataAccessWebException, NotAuthenticatedWebException { User user = userRestService.getUserFromIdentity(securityIdentity); try { - return exportService.getExportHistory(user); + return exportService.getExportHistory(user, pageNumber.orElseGet(() -> 0)); } catch (DataAccessException e) { throw new DataAccessWebException(e.getMessage(), e); } diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java index 075999f575..b5213acb75 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/Exports/ExportService.java @@ -47,8 +47,8 @@ public ExportService(AgroalConnectionFactory connectionFactory) throws DataAcces databaseServer = new DatabaseServerImpl(connectionFactory, connectionFactory.getKeyFactory()); } - public List getExportHistory(User user) throws DataAccessException { - return databaseServer.getUsersExportHistory(user); + public List getExportHistory(User user, int pageNumber) throws DataAccessException { + return databaseServer.getUsersExportHistory(user, pageNumber); } public Multi getExportStatuses(User user, long jobID) throws ObjectNotFoundException { diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java index a313ccfdba..deefbb6077 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java @@ -67,7 +67,7 @@ public void deleteExportHistory(Connection conn, String uri) throws SQLException } // sub selection of sim ref key for that export event, then tie it back to biomodel/sim for getting metadata (name, application, etc) - public List getExportHistoryForUser(Connection conn, User user) throws SQLException, JsonProcessingException, DataAccessException { + public List getExportHistoryForUser(Connection conn, User user, int pageNumber) throws SQLException, JsonProcessingException, DataAccessException { String sql = """ SELECT eh.*, sim.name as sim_name, bio.name as bio_name, bio.childSummaryLRG, bio.childSummarySML, math.name as math_model_name, sim.mathoverrides, sim.mathOverridesLRG, sim.mathOverridesSML, simContext.name as application_name, simContext.appComponentsLRG, simContext.appComponentsSML @@ -77,9 +77,12 @@ public List getExportHistoryForUser(Connection conn, User user) t LEFT JOIN vc_mathmodel math ON math.id = eh.mathmodel_ref LEFT JOIN vc_simcontext simContext ON simContext.mathRef = eh.math_ref WHERE user_ref = ? ORDER BY export_date DESC + OFFSET ? ROWS FETCH NEXT 100 ROWS ONLY """; PreparedStatement ps = conn.prepareStatement(sql); ps.setLong(1, Long.parseLong(user.getID().toString())); + pageNumber = (0 < pageNumber) && (pageNumber < 10000) ? pageNumber : 0; + ps.setInt(2, pageNumber * 100); ResultSet resultSet = ps.executeQuery(); List exportHistoryDBReps = new ArrayList<>(); while (resultSet.next()) { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java index a708d8b946..d5c7ac473c 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -2284,11 +2284,11 @@ public void insertExportHistory(User user, ExportHistoryDBRep exportHistoryValue } } - public List getUsersExportHistory(User user, boolean bEnableRetry) throws SQLException, DataAccessException { + public List getUsersExportHistory(User user, int pagingNumber, boolean bEnableRetry) throws SQLException, DataAccessException { Object lock = new Object(); Connection con = conFactory.getConnection(lock); try { - return exportHistoryDBDriver.getExportHistoryForUser(con, user); + return exportHistoryDBDriver.getExportHistoryForUser(con, user, pagingNumber); } catch (Throwable e) { lg.error(e.getMessage(),e); try { @@ -2298,7 +2298,7 @@ public List getUsersExportHistory(User user, boolean bEnableRetry } if (bEnableRetry && isBadConnection(con)) { conFactory.failed(con,lock); - return getUsersExportHistory(user, false); + return getUsersExportHistory(user, pagingNumber,false); }else{ handle_DataAccessException_SQLException(e); return null; // never gets here; diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java index 1d0aa4fb7a..1bf8e4c848 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java @@ -1365,9 +1365,9 @@ public void addExportHistory(User user, ExportHistoryDBRep exportHistory) throws } } - public List getUsersExportHistory(User user) throws DataAccessException { + public List getUsersExportHistory(User user, int pageNumber) throws DataAccessException { try { - return dbTop.getUsersExportHistory(user, true); + return dbTop.getUsersExportHistory(user, pageNumber,true); } catch (SQLException e) { throw new DataAccessException(e); } From 2a7bbbb8ab5fe875be356e18fafc4ab9bc5d56cf Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 7 Apr 2026 11:53:54 -0400 Subject: [PATCH 61/65] Generated Clients for Paging --- python-restclient/docs/ExportHistory.md | 3 - python-restclient/docs/ExportResourceApi.md | 10 +- .../vcell_client/api/export_resource_api.py | 17 +++ .../vcell_client/models/export_history.py | 10 +- tools/openapi.yaml | 15 +-- vcell-restclient/api/openapi.yaml | 19 ++- vcell-restclient/docs/ExportHistory.md | 3 - vcell-restclient/docs/ExportResourceApi.md | 20 +++- .../restclient/api/ExportResourceApi.java | 29 ++++- .../vcell/restclient/model/ExportHistory.java | 110 +----------------- .../openapi/api/export-resource.service.ts | 16 ++- .../api/export-resource.serviceInterface.ts | 3 +- .../modules/openapi/model/export-history.ts | 3 - 13 files changed, 95 insertions(+), 163 deletions(-) diff --git a/python-restclient/docs/ExportHistory.md b/python-restclient/docs/ExportHistory.md index 1e216d1762..4e0a56a60f 100644 --- a/python-restclient/docs/ExportHistory.md +++ b/python-restclient/docs/ExportHistory.md @@ -17,9 +17,6 @@ Name | Type | Description | Notes **variables** | **List[str]** | | [optional] **start_time_value** | **float** | | [optional] **end_time_value** | **float** | | [optional] -**saved_file_name_value** | **str** | | [optional] -**selected_z_slice** | **int** | | [optional] -**entire_z_stack** | **bool** | | [optional] **event_status** | [**ExportProgressType**](ExportProgressType.md) | | [optional] ## Example diff --git a/python-restclient/docs/ExportResourceApi.md b/python-restclient/docs/ExportResourceApi.md index 54dd5b77e2..243034843d 100644 --- a/python-restclient/docs/ExportResourceApi.md +++ b/python-restclient/docs/ExportResourceApi.md @@ -158,7 +158,7 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **get_export_history** -> List[ExportHistory] get_export_history() +> List[ExportHistory] get_export_history(page_number=page_number) @@ -187,9 +187,10 @@ configuration = vcell_client.Configuration( with vcell_client.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = vcell_client.ExportResourceApi(api_client) + page_number = 56 # int | (optional) try: - api_response = api_instance.get_export_history() + api_response = api_instance.get_export_history(page_number=page_number) print("The response of ExportResourceApi->get_export_history:\n") pprint(api_response) except Exception as e: @@ -199,7 +200,10 @@ with vcell_client.ApiClient(configuration) as api_client: ### Parameters -This endpoint does not need any parameter. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **page_number** | **int**| | [optional] ### Return type diff --git a/python-restclient/vcell_client/api/export_resource_api.py b/python-restclient/vcell_client/api/export_resource_api.py index 674f624751..1a495797be 100644 --- a/python-restclient/vcell_client/api/export_resource_api.py +++ b/python-restclient/vcell_client/api/export_resource_api.py @@ -616,6 +616,7 @@ def _export_status_serialize( @validate_call def get_export_history( self, + page_number: Optional[StrictInt] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -632,6 +633,8 @@ def get_export_history( """get_export_history + :param page_number: + :type page_number: int :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -655,6 +658,7 @@ def get_export_history( """ # noqa: E501 _param = self._get_export_history_serialize( + page_number=page_number, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -682,6 +686,7 @@ def get_export_history( @validate_call def get_export_history_with_http_info( self, + page_number: Optional[StrictInt] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -698,6 +703,8 @@ def get_export_history_with_http_info( """get_export_history + :param page_number: + :type page_number: int :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -721,6 +728,7 @@ def get_export_history_with_http_info( """ # noqa: E501 _param = self._get_export_history_serialize( + page_number=page_number, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -748,6 +756,7 @@ def get_export_history_with_http_info( @validate_call def get_export_history_without_preload_content( self, + page_number: Optional[StrictInt] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -764,6 +773,8 @@ def get_export_history_without_preload_content( """get_export_history + :param page_number: + :type page_number: int :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -787,6 +798,7 @@ def get_export_history_without_preload_content( """ # noqa: E501 _param = self._get_export_history_serialize( + page_number=page_number, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -809,6 +821,7 @@ def get_export_history_without_preload_content( def _get_export_history_serialize( self, + page_number, _request_auth, _content_type, _headers, @@ -830,6 +843,10 @@ def _get_export_history_serialize( # process the path parameters # process the query parameters + if page_number is not None: + + _query_params.append(('pageNumber', page_number)) + # process the header parameters # process the form parameters # process the body parameter diff --git a/python-restclient/vcell_client/models/export_history.py b/python-restclient/vcell_client/models/export_history.py index b411bd1997..cd2d206fb8 100644 --- a/python-restclient/vcell_client/models/export_history.py +++ b/python-restclient/vcell_client/models/export_history.py @@ -20,7 +20,7 @@ from datetime import datetime from typing import Any, ClassVar, Dict, List, Optional, Union -from pydantic import BaseModel, StrictBool, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, StrictFloat, StrictInt, StrictStr from pydantic import Field from vcell_client.models.export_format import ExportFormat from vcell_client.models.export_progress_type import ExportProgressType @@ -46,11 +46,8 @@ class ExportHistory(BaseModel): variables: Optional[List[StrictStr]] = None start_time_value: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="startTimeValue") end_time_value: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="endTimeValue") - saved_file_name_value: Optional[StrictStr] = Field(default=None, alias="savedFileNameValue") - selected_z_slice: Optional[StrictInt] = Field(default=None, alias="selectedZSlice") - entire_z_stack: Optional[StrictBool] = Field(default=None, alias="entireZStack") event_status: Optional[ExportProgressType] = Field(default=None, alias="eventStatus") - __properties: ClassVar[List[str]] = ["exportJobID", "simulationRef", "bioModelRef", "mathModelRef", "mathRef", "exportFormat", "exportDate", "uri", "simName", "modelName", "variables", "startTimeValue", "endTimeValue", "savedFileNameValue", "selectedZSlice", "entireZStack", "eventStatus"] + __properties: ClassVar[List[str]] = ["exportJobID", "simulationRef", "bioModelRef", "mathModelRef", "mathRef", "exportFormat", "exportDate", "uri", "simName", "modelName", "variables", "startTimeValue", "endTimeValue", "eventStatus"] model_config = { "populate_by_name": True, @@ -118,9 +115,6 @@ def from_dict(cls, obj: Dict) -> Self: "variables": obj.get("variables"), "startTimeValue": obj.get("startTimeValue"), "endTimeValue": obj.get("endTimeValue"), - "savedFileNameValue": obj.get("savedFileNameValue"), - "selectedZSlice": obj.get("selectedZSlice"), - "entireZStack": obj.get("entireZStack"), "eventStatus": obj.get("eventStatus") }) return _obj diff --git a/tools/openapi.yaml b/tools/openapi.yaml index cb35d4c41e..3315d9370b 100644 --- a/tools/openapi.yaml +++ b/tools/openapi.yaml @@ -466,6 +466,14 @@ paths: tags: - Export Resource operationId: getExportHistory + parameters: + - name: pageNumber + in: query + required: false + schema: + format: int32 + default: "0" + type: integer responses: "200": description: OK @@ -2608,13 +2616,6 @@ components: endTimeValue: format: double type: number - savedFileNameValue: - type: string - selectedZSlice: - format: int32 - type: integer - entireZStack: - type: boolean eventStatus: $ref: '#/components/schemas/ExportProgressType' ExportProgressType: diff --git a/vcell-restclient/api/openapi.yaml b/vcell-restclient/api/openapi.yaml index d6a2f08b92..19cbedcf55 100644 --- a/vcell-restclient/api/openapi.yaml +++ b/vcell-restclient/api/openapi.yaml @@ -502,6 +502,15 @@ paths: /api/v1/export/history: get: operationId: getExportHistory + parameters: + - explode: true + in: query + name: pageNumber + required: false + schema: + format: int32 + type: integer + style: form responses: "200": content: @@ -3015,9 +3024,6 @@ components: uri: uri modelName: modelName exportDate: 2022-03-10T16:15:50Z - savedFileNameValue: savedFileNameValue - entireZStack: true - selectedZSlice: 5 eventStatus: null simName: simName exportJobID: 0 @@ -3057,13 +3063,6 @@ components: endTimeValue: format: double type: number - savedFileNameValue: - type: string - selectedZSlice: - format: int32 - type: integer - entireZStack: - type: boolean eventStatus: $ref: '#/components/schemas/ExportProgressType' type: object diff --git a/vcell-restclient/docs/ExportHistory.md b/vcell-restclient/docs/ExportHistory.md index 600c70906d..282b209b32 100644 --- a/vcell-restclient/docs/ExportHistory.md +++ b/vcell-restclient/docs/ExportHistory.md @@ -20,9 +20,6 @@ |**variables** | **List<String>** | | [optional] | |**startTimeValue** | **Double** | | [optional] | |**endTimeValue** | **Double** | | [optional] | -|**savedFileNameValue** | **String** | | [optional] | -|**selectedZSlice** | **Integer** | | [optional] | -|**entireZStack** | **Boolean** | | [optional] | |**eventStatus** | **ExportProgressType** | | [optional] | diff --git a/vcell-restclient/docs/ExportResourceApi.md b/vcell-restclient/docs/ExportResourceApi.md index 9e2e3780f2..cb8abaddfd 100644 --- a/vcell-restclient/docs/ExportResourceApi.md +++ b/vcell-restclient/docs/ExportResourceApi.md @@ -307,7 +307,7 @@ ApiResponse<[**List<ExportEvent>**](ExportEvent.md)> ## getExportHistory -> List getExportHistory() +> List getExportHistory(pageNumber) @@ -329,8 +329,9 @@ public class Example { ExportResourceApi apiInstance = new ExportResourceApi(defaultClient); + Integer pageNumber = 56; // Integer | try { - List result = apiInstance.getExportHistory(); + List result = apiInstance.getExportHistory(pageNumber); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling ExportResourceApi#getExportHistory"); @@ -345,7 +346,10 @@ public class Example { ### Parameters -This endpoint does not need any parameter. + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **pageNumber** | **Integer**| | [optional] | ### Return type @@ -371,7 +375,7 @@ This endpoint does not need any parameter. ## getExportHistoryWithHttpInfo -> ApiResponse> getExportHistory getExportHistoryWithHttpInfo() +> ApiResponse> getExportHistory getExportHistoryWithHttpInfo(pageNumber) @@ -394,8 +398,9 @@ public class Example { ExportResourceApi apiInstance = new ExportResourceApi(defaultClient); + Integer pageNumber = 56; // Integer | try { - ApiResponse> response = apiInstance.getExportHistoryWithHttpInfo(); + ApiResponse> response = apiInstance.getExportHistoryWithHttpInfo(pageNumber); System.out.println("Status code: " + response.getStatusCode()); System.out.println("Response headers: " + response.getHeaders()); System.out.println("Response body: " + response.getData()); @@ -412,7 +417,10 @@ public class Example { ### Parameters -This endpoint does not need any parameter. + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **pageNumber** | **Integer**| | [optional] | ### Return type diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/api/ExportResourceApi.java b/vcell-restclient/src/main/java/org/vcell/restclient/api/ExportResourceApi.java index efedd7228c..6cbab8d3c0 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/api/ExportResourceApi.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/api/ExportResourceApi.java @@ -242,22 +242,24 @@ private HttpRequest.Builder exportStatusRequestBuilder(Long timestamp) throws Ap /** * * + * @param pageNumber (optional) * @return List<ExportHistory> * @throws ApiException if fails to make API call */ - public List getExportHistory() throws ApiException { - ApiResponse> localVarResponse = getExportHistoryWithHttpInfo(); + public List getExportHistory(Integer pageNumber) throws ApiException { + ApiResponse> localVarResponse = getExportHistoryWithHttpInfo(pageNumber); return localVarResponse.getData(); } /** * * + * @param pageNumber (optional) * @return ApiResponse<List<ExportHistory>> * @throws ApiException if fails to make API call */ - public ApiResponse> getExportHistoryWithHttpInfo() throws ApiException { - HttpRequest.Builder localVarRequestBuilder = getExportHistoryRequestBuilder(); + public ApiResponse> getExportHistoryWithHttpInfo(Integer pageNumber) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = getExportHistoryRequestBuilder(pageNumber); try { HttpResponse localVarResponse = memberVarHttpClient.send( localVarRequestBuilder.build(), @@ -285,13 +287,28 @@ public ApiResponse> getExportHistoryWithHttpInfo() throws Ap } } - private HttpRequest.Builder getExportHistoryRequestBuilder() throws ApiException { + private HttpRequest.Builder getExportHistoryRequestBuilder(Integer pageNumber) throws ApiException { HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); String localVarPath = "/api/v1/export/history"; - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + List localVarQueryParams = new ArrayList<>(); + StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + String localVarQueryParameterBaseName; + localVarQueryParameterBaseName = "pageNumber"; + localVarQueryParams.addAll(ApiClient.parameterToPairs("pageNumber", pageNumber)); + + if (!localVarQueryParams.isEmpty() || localVarQueryStringJoiner.length() != 0) { + StringJoiner queryJoiner = new StringJoiner("&"); + localVarQueryParams.forEach(p -> queryJoiner.add(p.getName() + '=' + p.getValue())); + if (localVarQueryStringJoiner.length() != 0) { + queryJoiner.add(localVarQueryStringJoiner.toString()); + } + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath + '?' + queryJoiner.toString())); + } else { + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + } localVarRequestBuilder.header("Accept", "application/json"); diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java index 0011cfa365..c8f1561c57 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/ExportHistory.java @@ -50,9 +50,6 @@ ExportHistory.JSON_PROPERTY_VARIABLES, ExportHistory.JSON_PROPERTY_START_TIME_VALUE, ExportHistory.JSON_PROPERTY_END_TIME_VALUE, - ExportHistory.JSON_PROPERTY_SAVED_FILE_NAME_VALUE, - ExportHistory.JSON_PROPERTY_SELECTED_Z_SLICE, - ExportHistory.JSON_PROPERTY_ENTIRE_Z_STACK, ExportHistory.JSON_PROPERTY_EVENT_STATUS }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") @@ -96,15 +93,6 @@ public class ExportHistory { public static final String JSON_PROPERTY_END_TIME_VALUE = "endTimeValue"; private Double endTimeValue; - public static final String JSON_PROPERTY_SAVED_FILE_NAME_VALUE = "savedFileNameValue"; - private String savedFileNameValue; - - public static final String JSON_PROPERTY_SELECTED_Z_SLICE = "selectedZSlice"; - private Integer selectedZSlice; - - public static final String JSON_PROPERTY_ENTIRE_Z_STACK = "entireZStack"; - private Boolean entireZStack; - public static final String JSON_PROPERTY_EVENT_STATUS = "eventStatus"; private ExportProgressType eventStatus; @@ -444,81 +432,6 @@ public void setEndTimeValue(Double endTimeValue) { } - public ExportHistory savedFileNameValue(String savedFileNameValue) { - this.savedFileNameValue = savedFileNameValue; - return this; - } - - /** - * Get savedFileNameValue - * @return savedFileNameValue - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_SAVED_FILE_NAME_VALUE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public String getSavedFileNameValue() { - return savedFileNameValue; - } - - - @JsonProperty(JSON_PROPERTY_SAVED_FILE_NAME_VALUE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setSavedFileNameValue(String savedFileNameValue) { - this.savedFileNameValue = savedFileNameValue; - } - - - public ExportHistory selectedZSlice(Integer selectedZSlice) { - this.selectedZSlice = selectedZSlice; - return this; - } - - /** - * Get selectedZSlice - * @return selectedZSlice - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_SELECTED_Z_SLICE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public Integer getSelectedZSlice() { - return selectedZSlice; - } - - - @JsonProperty(JSON_PROPERTY_SELECTED_Z_SLICE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setSelectedZSlice(Integer selectedZSlice) { - this.selectedZSlice = selectedZSlice; - } - - - public ExportHistory entireZStack(Boolean entireZStack) { - this.entireZStack = entireZStack; - return this; - } - - /** - * Get entireZStack - * @return entireZStack - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_ENTIRE_Z_STACK) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public Boolean getEntireZStack() { - return entireZStack; - } - - - @JsonProperty(JSON_PROPERTY_ENTIRE_Z_STACK) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setEntireZStack(Boolean entireZStack) { - this.entireZStack = entireZStack; - } - - public ExportHistory eventStatus(ExportProgressType eventStatus) { this.eventStatus = eventStatus; return this; @@ -569,15 +482,12 @@ public boolean equals(Object o) { Objects.equals(this.variables, exportHistory.variables) && Objects.equals(this.startTimeValue, exportHistory.startTimeValue) && Objects.equals(this.endTimeValue, exportHistory.endTimeValue) && - Objects.equals(this.savedFileNameValue, exportHistory.savedFileNameValue) && - Objects.equals(this.selectedZSlice, exportHistory.selectedZSlice) && - Objects.equals(this.entireZStack, exportHistory.entireZStack) && Objects.equals(this.eventStatus, exportHistory.eventStatus); } @Override public int hashCode() { - return Objects.hash(exportJobID, simulationRef, bioModelRef, mathModelRef, mathRef, exportFormat, exportDate, uri, simName, modelName, variables, startTimeValue, endTimeValue, savedFileNameValue, selectedZSlice, entireZStack, eventStatus); + return Objects.hash(exportJobID, simulationRef, bioModelRef, mathModelRef, mathRef, exportFormat, exportDate, uri, simName, modelName, variables, startTimeValue, endTimeValue, eventStatus); } @Override @@ -597,9 +507,6 @@ public String toString() { sb.append(" variables: ").append(toIndentedString(variables)).append("\n"); sb.append(" startTimeValue: ").append(toIndentedString(startTimeValue)).append("\n"); sb.append(" endTimeValue: ").append(toIndentedString(endTimeValue)).append("\n"); - sb.append(" savedFileNameValue: ").append(toIndentedString(savedFileNameValue)).append("\n"); - sb.append(" selectedZSlice: ").append(toIndentedString(selectedZSlice)).append("\n"); - sb.append(" entireZStack: ").append(toIndentedString(entireZStack)).append("\n"); sb.append(" eventStatus: ").append(toIndentedString(eventStatus)).append("\n"); sb.append("}"); return sb.toString(); @@ -717,21 +624,6 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format("%sendTimeValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getEndTimeValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } - // add `savedFileNameValue` to the URL query string - if (getSavedFileNameValue() != null) { - joiner.add(String.format("%ssavedFileNameValue%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSavedFileNameValue()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - - // add `selectedZSlice` to the URL query string - if (getSelectedZSlice() != null) { - joiner.add(String.format("%sselectedZSlice%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getSelectedZSlice()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - - // add `entireZStack` to the URL query string - if (getEntireZStack() != null) { - joiner.add(String.format("%sentireZStack%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getEntireZStack()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - // add `eventStatus` to the URL query string if (getEventStatus() != null) { joiner.add(String.format("%seventStatus%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getEventStatus()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); diff --git a/webapp-ng/src/app/core/modules/openapi/api/export-resource.service.ts b/webapp-ng/src/app/core/modules/openapi/api/export-resource.service.ts index 915e6d788a..5a9cee11ac 100644 --- a/webapp-ng/src/app/core/modules/openapi/api/export-resource.service.ts +++ b/webapp-ng/src/app/core/modules/openapi/api/export-resource.service.ts @@ -240,13 +240,20 @@ export class ExportResourceService implements ExportResourceServiceInterface { } /** + * @param pageNumber * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getExportHistory(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public getExportHistory(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>>; - public getExportHistory(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>>; - public getExportHistory(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + public getExportHistory(pageNumber?: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getExportHistory(pageNumber?: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>>; + public getExportHistory(pageNumber?: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>>; + public getExportHistory(pageNumber?: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); + if (pageNumber !== undefined && pageNumber !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + pageNumber, 'pageNumber'); + } let localVarHeaders = this.defaultHeaders; @@ -289,6 +296,7 @@ export class ExportResourceService implements ExportResourceServiceInterface { return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, + params: localVarQueryParameters, responseType: responseType_, withCredentials: this.configuration.withCredentials, headers: localVarHeaders, diff --git a/webapp-ng/src/app/core/modules/openapi/api/export-resource.serviceInterface.ts b/webapp-ng/src/app/core/modules/openapi/api/export-resource.serviceInterface.ts index cdb1b10114..c3bd1435ed 100644 --- a/webapp-ng/src/app/core/modules/openapi/api/export-resource.serviceInterface.ts +++ b/webapp-ng/src/app/core/modules/openapi/api/export-resource.serviceInterface.ts @@ -44,7 +44,8 @@ export interface ExportResourceServiceInterface { /** * * + * @param pageNumber */ - getExportHistory(extraHttpRequestParams?: any): Observable>; + getExportHistory(pageNumber?: number, extraHttpRequestParams?: any): Observable>; } diff --git a/webapp-ng/src/app/core/modules/openapi/model/export-history.ts b/webapp-ng/src/app/core/modules/openapi/model/export-history.ts index b3f505b2fa..41cab3eae6 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/export-history.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/export-history.ts @@ -27,9 +27,6 @@ export interface ExportHistory { variables?: Array; startTimeValue?: number; endTimeValue?: number; - savedFileNameValue?: string; - selectedZSlice?: number; - entireZStack?: boolean; eventStatus?: ExportProgressType; } export namespace ExportHistory { From 8dadc3f832cdd22197cb0d3d35456101ab78d44e Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 7 Apr 2026 11:54:25 -0400 Subject: [PATCH 62/65] Paging Test --- .../exports/ExportHistoryClientTest.java | 20 +++++++++++++++++-- .../restq/exports/ExportHistoryDBTest.java | 8 ++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java index 27c0a1ede4..dfe3130b9f 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryClientTest.java @@ -68,7 +68,7 @@ public void testExportRequestClient() throws Exception { N5ExportRequest exportRequest = ExportHelper.getValidExportRequestDTO(0, 1, dataServer, frapModel.getSimulation(0), frapModel); ExportEvent completedExport = ExportHelper.exportAndWait(exportResourceApi, exportRequest); - List exportHistories = exportResourceApi.getExportHistory(); + List exportHistories = exportResourceApi.getExportHistory(0); Assertions.assertFalse(exportHistories.isEmpty()); Assertions.assertEquals(exportHistories.size(), 1); Assertions.assertEquals(exportHistories.get(0).getExportJobID(), completedExport.getJobID()); @@ -86,7 +86,7 @@ public void testExportHistorySequence() throws Exception { frapModel.getSimulation(0), frapModel); ExportEvent completedExport1 = ExportHelper.exportAndWait(exportResourceApi, exportRequest); ExportEvent completedExport2 = ExportHelper.exportAndWait(exportResourceApi, exportRequest2); - List exportHistories = exportResourceApi.getExportHistory(); + List exportHistories = exportResourceApi.getExportHistory(0); Assertions.assertFalse(exportHistories.isEmpty()); Assertions.assertEquals(exportHistories.size(), 2); @@ -96,6 +96,22 @@ public void testExportHistorySequence() throws Exception { Assertions.assertTrue(exportHistories.get(0).getExportDate().isAfter(exportHistories.get(1).getExportDate())); } + @Test + public void testExportPaging() throws Exception { + ExportResourceApi exportResourceApi = new ExportResourceApi(aliceAPIClient); + N5ExportRequest exportRequest = ExportHelper.getValidExportRequestDTO(0, 1, dataServer, + frapModel.getSimulation(0), frapModel); + N5ExportRequest exportRequest2 = ExportHelper.getValidExportRequestDTO(2, 4, dataServer, + frapModel.getSimulation(0), frapModel); + ExportEvent completedExport1 = ExportHelper.exportAndWait(exportResourceApi, exportRequest); + ExportEvent completedExport2 = ExportHelper.exportAndWait(exportResourceApi, exportRequest2); + List exportHistories = exportResourceApi.getExportHistory(0); + + Assertions.assertEquals(exportHistories.size(), 2); + exportHistories = exportResourceApi.getExportHistory(1); + Assertions.assertTrue(exportHistories.isEmpty()); + } + private boolean requestEqualHistory(N5ExportRequest request, ExportHistory history){ List allTimes = request.getStandardExportInformation().getTimeSpecs().getAllTimes(); boolean modelEqual = request.getStandardExportInformation().getBioModelKey().equals(history.getBioModelRef()); diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index fbca89fe84..c5a956fa57 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -107,7 +107,7 @@ public void testAddExportHistory() { driver.addExportHistory(conn, user, rep, agroalConnectionFactory.getKeyFactory()); try { - List exportHistoryRecord = driver.getExportHistoryForUser(conn, user); + List exportHistoryRecord = driver.getExportHistoryForUser(conn, user, 0); Assertions.assertEquals(1, exportHistoryRecord.size(), "expected one record"); Assertions.assertTrue(historyDBEqualHistory(rep, exportHistoryRecord.get(0))); Assertions.assertEquals(savedBioModel.getName(), exportHistoryRecord.get(0).modelName()); @@ -141,13 +141,13 @@ public void testDeleteExportHistory() throws SQLException { ); - List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + List retrievedExportHistory = driver.getExportHistoryForUser(conn, user, 0); Assertions.assertEquals(2, retrievedExportHistory.size(), "expected two records"); Assertions.assertTrue(historyDBEqualHistory(exportHistoryDBRep, retrievedExportHistory.get(0))); Assertions.assertTrue(historyDBEqualHistory(notDeletedRep, retrievedExportHistory.get(1))); driver.deleteExportHistory(conn, exportHistoryDBRep.uri()); - retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + retrievedExportHistory = driver.getExportHistoryForUser(conn, user, 0); Assertions.assertEquals(1, retrievedExportHistory.size(), "expected one record after deletion"); Assertions.assertTrue(historyDBEqualHistory(notDeletedRep, retrievedExportHistory.get(0))); } catch (DataAccessException | JsonProcessingException e) { @@ -174,7 +174,7 @@ public void testGetExportHistory() throws SQLException, DataAccessException, Jso agroalConnectionFactory.getKeyFactory() ); - List retrievedExportHistory = driver.getExportHistoryForUser(conn, user); + List retrievedExportHistory = driver.getExportHistoryForUser(conn, user, 0); Assertions.assertEquals(2, retrievedExportHistory.size(), "expected two records"); Assertions.assertTrue(historyDBEqualHistory(exportHistoryDBRep, retrievedExportHistory.get(0))); Assertions.assertTrue(historyDBEqualHistory(exportHistoryDBRep1, retrievedExportHistory.get(1))); From 388bffe7e502c005f09694d713b5e387c9d06757 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 17 Apr 2026 11:20:19 -0400 Subject: [PATCH 63/65] Allow 1sec Time Difference in Test --- .../test/java/org/vcell/restq/exports/ExportHistoryDBTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index c5a956fa57..3ae9c00800 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -184,7 +184,7 @@ public void testGetExportHistory() throws SQLException, DataAccessException, Jso private boolean historyDBEqualHistory(ExportHistoryDBRep dbRep, ExportHistory history) { return dbRep.simulationRef().equals(history.simulationRef()) && dbRep.exportFormat().equals(history.exportFormat()) && - history.exportDate().equals(dbRep.exportDate().toInstant()) && + Math.abs(history.exportDate().toEpochMilli() - dbRep.exportDate().getTime()) <= 1000 && dbRep.uri().equals(history.uri()) && List.of(dbRep.variables()).equals(List.of(history.variables())) && Double.compare(dbRep.startTimeValue(), history.startTimeValue()) == 0 && From 62cd24c4c50189b641d90899880d02aad67d10e2 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 28 Apr 2026 14:57:58 -0400 Subject: [PATCH 64/65] Update Export Table Name --- vcell-rest/src/main/resources/scripts/init.sql | 4 ++-- .../src/test/java/org/vcell/restq/TestEndpointUtils.java | 3 +-- .../java/org/vcell/restq/exports/ExportHistoryDBTest.java | 2 +- .../main/java/cbit/vcell/exports/ExportHistoryTable.java | 2 +- .../main/java/cbit/vcell/modeldb/SQLCreateAllTables.java | 8 ++++---- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 97877c86a7..64e9fcd0e3 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -76,7 +76,7 @@ CREATE TABLE vc_userlogininfo(id bigint PRIMARY KEY,userRef bigint NOT NULL REFE CREATE TABLE vc_metadata(id bigint PRIMARY KEY,bioModelRef bigint NOT NULL REFERENCES vc_biomodel(id) ON DELETE CASCADE,vcMetaDataLarge text ,vcMetaDataSmall varchar(4000) ); CREATE TABLE vc_simdelfromdisk(deldate varchar(20) ,userid varchar(255) NOT NULL,userkey bigint ,simid bigint ,simpref bigint ,simdate varchar(20) ,simname varchar(255) NOT NULL,status varchar(10) ,numfiles bigint ,totalsize bigint ); CREATE TABLE vc_useridentity(id bigint PRIMARY KEY,userRef bigint NOT NULL REFERENCES vc_userinfo(id),authSubject varchar(128) NOT NULL,authIssuer varchar(128) NOT NULL,insertDate timestamp NOT NULL); -CREATE TABLE vc_simulation_export_history(id bigint PRIMARY KEY,job_id bigint NOT NULL,user_ref bigint NOT NULL REFERENCES vc_userinfo(id),biomodel_ref bigint REFERENCES vc_biomodel(id),mathmodel_ref bigint REFERENCES vc_mathmodel(id),simulation_ref bigint NOT NULL REFERENCES vc_simulation(id),math_ref bigint NOT NULL REFERENCES vc_math(id),export_format varchar(50) NOT NULL,export_date timestamp NOT NULL,uri varchar(1024) NOT NULL,variables varchar(4000) [] NOT NULL,start_time numeric NOT NULL,end_time numeric NOT NULL,event_status varchar(50) NOT NULL); +CREATE TABLE vc_simulation_export_job(id bigint PRIMARY KEY,job_id bigint NOT NULL,user_ref bigint NOT NULL REFERENCES vc_userinfo(id),biomodel_ref bigint REFERENCES vc_biomodel(id),mathmodel_ref bigint REFERENCES vc_mathmodel(id),simulation_ref bigint NOT NULL REFERENCES vc_simulation(id),math_ref bigint NOT NULL REFERENCES vc_math(id),export_format varchar(50) NOT NULL,export_date timestamp NOT NULL,uri varchar(1024) NOT NULL,variables varchar(4000) [] NOT NULL,start_time numeric NOT NULL,end_time numeric NOT NULL,event_status varchar(50) NOT NULL); CREATE VIEW public.dual AS SELECT CAST('X' as varchar) AS dummy; @@ -88,7 +88,7 @@ CREATE INDEX geom_extentref ON vc_geometry(extentRef); CREATE INDEX geom_imageref ON vc_geometry(imageRef); CREATE INDEX mathdesc_geomref ON vc_math(geometryRef); CREATE INDEX simcstat_simcref ON vc_simcontextstat(simContextRef); -CREATE INDEX idx_export_history_simulation_ref ON vc_simulation_export_history(simulation_ref); +CREATE INDEX idx_export_history_simulation_ref ON vc_simulation_export_job(simulation_ref); INSERT INTO vc_userinfo VALUES ( 0,'void','1700596370242','void@example.com','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'B9BDD75BC5382CA83D5AB82172A98D869555899C' ); diff --git a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java index 5db28bc190..79e1eb5f4c 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -186,7 +186,7 @@ public static DataServerImpl createDataServerImpl() throws FileNotFoundException public static void clearAllBioModelEntries(AgroalConnectionFactory agroalConnectionFactory) throws DataAccessException, SQLException { Object object = new Object(); Connection connection = agroalConnectionFactory.getConnection(object); - connection.prepareStatement("DELETE FROM VC_SIMULATION_EXPORT_HISTORY").execute(); + connection.prepareStatement("DELETE FROM VC_SIMULATION_EXPORT_JOB").execute(); connection.prepareStatement("DELETE FROM VC_BIOMODEL").execute(); connection.prepareStatement("DELETE FROM VC_BIOMODELXML").execute(); connection.prepareStatement("DELETE FROM VC_BIOMODELSIM").execute(); @@ -195,7 +195,6 @@ public static void clearAllBioModelEntries(AgroalConnectionFactory agroalConnect connection.prepareStatement("DELETE FROM VC_MATHMODELSIM").execute(); connection.prepareStatement("DELETE FROM VC_SIMCONTEXT").execute(); - connection.prepareStatement("DELETE FROM VC_SIMULATION_EXPORT_HISTORY").execute(); connection.prepareStatement("DELETE FROM VC_SIMULATION").execute(); connection.prepareStatement("DELETE FROM VC_MATHMODELXML").execute(); diff --git a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java index 3ae9c00800..3cf011aab9 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/exports/ExportHistoryDBTest.java @@ -84,7 +84,7 @@ private ExportHistoryDBRep getExportHistoryRep(int jobID, String uri, Timestamp @AfterEach public void cleanUp() throws SQLException, DataAccessException { - String sql = "DELETE FROM VC_SIMULATION_EXPORT_HISTORY"; + String sql = "DELETE FROM VC_SIMULATION_EXPORT_JOB"; Connection connection = agroalConnectionFactory.getConnection(null); connection.prepareStatement(sql).execute(); connection.commit(); diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java index f3cb77da84..fa3f1e3ffb 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryTable.java @@ -12,7 +12,7 @@ import java.util.StringJoiner; public class ExportHistoryTable extends Table { - private static final String TABLE_NAME = "vc_simulation_export_history"; + private static final String TABLE_NAME = "vc_simulation_export_job"; // public final Field id = new Field(id_ColumnName, Field.SQLDataType.integer,"PRIMARY KEY"); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/SQLCreateAllTables.java b/vcell-server/src/main/java/cbit/vcell/modeldb/SQLCreateAllTables.java index e4ed9506ec..c504b938ab 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/SQLCreateAllTables.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/SQLCreateAllTables.java @@ -206,8 +206,8 @@ private static void destroyAndRecreateTables(ConnectionFactory conFactory, KeyFa createIndex(con,"geom_imageref",cbit.vcell.modeldb.GeometryTable.table,cbit.vcell.modeldb.GeometryTable.table.imageRef, dbSyntax); createIndex(con,"mathdesc_geomref",cbit.vcell.modeldb.MathDescTable.table,cbit.vcell.modeldb.MathDescTable.table.geometryRef, dbSyntax); createIndex(con,"simcstat_simcref",cbit.vcell.modeldb.SimContextStatTable.table,cbit.vcell.modeldb.SimContextStatTable.table.simContextRef, dbSyntax); - createIndex(con, "export_history_time", ExportHistoryTable.table, ExportHistoryTable.table.exportDate, dbSyntax); - createIndex(con, "export_history_userref", ExportHistoryTable.table, ExportHistoryTable.table.userRef, dbSyntax); + createIndex(con, "export_job_time", ExportHistoryTable.table, ExportHistoryTable.table.exportDate, dbSyntax); + createIndex(con, "export_job_userref", ExportHistoryTable.table, ExportHistoryTable.table.userRef, dbSyntax); } con.commit(); } catch (SQLException exc) { @@ -406,8 +406,8 @@ public static void writeScript(DatabaseSyntax dbSyntax, boolean bootstrapData, W scriptWriter.write(getCreateIndexSQL("geom_imageref", GeometryTable.table, GeometryTable.table.imageRef) + ";\n"); scriptWriter.write(getCreateIndexSQL("mathdesc_geomref", MathDescTable.table, MathDescTable.table.geometryRef) + ";\n"); scriptWriter.write(getCreateIndexSQL("simcstat_simcref", SimContextStatTable.table, SimContextStatTable.table.simContextRef) + ";\n"); - scriptWriter.write(getCreateIndexSQL("export_history_userref", ExportHistoryTable.table, ExportHistoryTable.table.userRef) + ";\n"); - scriptWriter.write(getCreateIndexSQL("export_history_time", ExportHistoryTable.table, ExportHistoryTable.table.exportDate) + ";\n"); + scriptWriter.write(getCreateIndexSQL("export_job_userref", ExportHistoryTable.table, ExportHistoryTable.table.userRef) + ";\n"); + scriptWriter.write(getCreateIndexSQL("export_job_time", ExportHistoryTable.table, ExportHistoryTable.table.exportDate) + ";\n"); scriptWriter.write("\n"); if (bootstrapData) { KeyFactory bootstrapKeyFactory = new KeyFactory() { From 140c02dfe1f4a7714b360a530504ed1b20b19042 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 28 Apr 2026 14:58:47 -0400 Subject: [PATCH 65/65] Use Table Variable Instead of Literal Strings --- .../vcell/exports/ExportHistoryDBDriver.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java index deefbb6077..a559783336 100644 --- a/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/exports/ExportHistoryDBDriver.java @@ -1,5 +1,6 @@ package cbit.vcell.exports; +import cbit.vcell.modeldb.*; import com.fasterxml.jackson.core.JsonProcessingException; import org.vcell.db.DatabaseSyntax; import org.vcell.db.KeyFactory; @@ -59,7 +60,7 @@ public void addExportHistory(Connection conn, User user, ExportHistoryDBRep expo public void deleteExportHistory(Connection conn, String uri) throws SQLException { // Concern, data id could mean multiple items get deleted - String deleteSQL = "DELETE FROM vc_simulation_export_history WHERE uri = ?"; + String deleteSQL = "DELETE FROM " + ExportHistoryTable.table.tableName + " WHERE " + ExportHistoryTable.table.uri.getUnqualifiedColName() + " = ?"; try (PreparedStatement psDel = conn.prepareStatement(deleteSQL)) { psDel.setString(1, uri); psDel.executeUpdate(); @@ -68,18 +69,18 @@ public void deleteExportHistory(Connection conn, String uri) throws SQLException // sub selection of sim ref key for that export event, then tie it back to biomodel/sim for getting metadata (name, application, etc) public List getExportHistoryForUser(Connection conn, User user, int pageNumber) throws SQLException, JsonProcessingException, DataAccessException { - String sql = """ - SELECT eh.*, sim.name as sim_name, bio.name as bio_name, bio.childSummaryLRG, bio.childSummarySML, math.name as math_model_name, - sim.mathoverrides, sim.mathOverridesLRG, sim.mathOverridesSML, simContext.name as application_name, simContext.appComponentsLRG, simContext.appComponentsSML - FROM vc_simulation_export_history eh - INNER JOIN vc_simulation sim ON sim.id = eh.simulation_ref - LEFT JOIN vc_biomodel bio ON bio.id = eh.biomodel_ref - LEFT JOIN vc_mathmodel math ON math.id = eh.mathmodel_ref - LEFT JOIN vc_simcontext simContext ON simContext.mathRef = eh.math_ref - WHERE user_ref = ? ORDER BY export_date DESC - OFFSET ? ROWS FETCH NEXT 100 ROWS ONLY -"""; - PreparedStatement ps = conn.prepareStatement(sql); + String properSQL = "SELECT eh.*, sim." + SimulationTable.table.name.getUnqualifiedColName() + + " as sim_name, bio." + BioModelTable.table.name.getUnqualifiedColName() + + " as bio_name, math." + MathModelTable.table.name.getUnqualifiedColName() + + " as math_model_name, simContext." + SimContextTable.table.name.getUnqualifiedColName() + " as application_name" + + " FROM " + ExportHistoryTable.table.tableName + " eh " + + " INNER JOIN " + SimulationTable.table.tableName + " sim ON sim." + SimulationTable.table.id.getUnqualifiedColName() + " = eh." + ExportHistoryTable.table.simulationRef.getUnqualifiedColName() + + " LEFT JOIN " + BioModelTable.table.tableName + " bio ON bio." + BioModelTable.table.id.getUnqualifiedColName() + " = eh." + ExportHistoryTable.table.bioModelRef.getUnqualifiedColName() + + " LEFT JOIN " + MathDescTable.table.tableName + " math ON math." + MathModelTable.table.id.getUnqualifiedColName() + " = eh." + ExportHistoryTable.table.mathModelRef.getUnqualifiedColName() + + " LEFT JOIN " + SimContextTable.table.tableName + " simContext ON simContext." + SimContextTable.table.id.getUnqualifiedColName() + " = eh." + ExportHistoryTable.table.mathRef.getUnqualifiedColName() + + " WHERE " + ExportHistoryTable.table.userRef.getUnqualifiedColName() + " = ? ORDER BY " + ExportHistoryTable.table.exportDate.getUnqualifiedColName() + " DESC OFFSET ? ROWS FETCH NEXT 100 ROWS ONLY"; + + PreparedStatement ps = conn.prepareStatement(properSQL); ps.setLong(1, Long.parseLong(user.getID().toString())); pageNumber = (0 < pageNumber) && (pageNumber < 10000) ? pageNumber : 0; ps.setInt(2, pageNumber * 100);