From f954a29f3a157abdbcbbf737095eac3b4c3fa3cb Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 13 Jun 2025 11:27:07 -0400 Subject: [PATCH 01/13] Grab the VCell Support Key On Startup --- .../cbit/vcell/resource/PropertyLoader.java | 1 + .../java/org/vcell/restq/StartUpTasks.java | 32 +++++++++++++++++++ .../cbit/vcell/modeldb/AdminDBTopLevel.java | 20 ++++++++++++ .../java/cbit/vcell/modeldb/UserDbDriver.java | 26 ++++++++++++++- 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 vcell-rest/src/main/java/org/vcell/restq/StartUpTasks.java diff --git a/vcell-core/src/main/java/cbit/vcell/resource/PropertyLoader.java b/vcell-core/src/main/java/cbit/vcell/resource/PropertyLoader.java index d052573344..5d062c4336 100644 --- a/vcell-core/src/main/java/cbit/vcell/resource/PropertyLoader.java +++ b/vcell-core/src/main/java/cbit/vcell/resource/PropertyLoader.java @@ -57,6 +57,7 @@ public static void setConfigProvider(VCellConfigProvider configProvider) { public static final String ADMINISTRATOR_ID = "2"; public static final String TESTACCOUNT_USERID = "vcellNagios"; public static final String VCELL_SUPPORT_USERID = "VCellSupport"; + public static final String vcellSupportId = record("vcell.user.support", ValueType.GEN); public static final String vcellServerIDProperty = record("vcell.server.id",ValueType.GEN); diff --git a/vcell-rest/src/main/java/org/vcell/restq/StartUpTasks.java b/vcell-rest/src/main/java/org/vcell/restq/StartUpTasks.java new file mode 100644 index 0000000000..fb7c493124 --- /dev/null +++ b/vcell-rest/src/main/java/org/vcell/restq/StartUpTasks.java @@ -0,0 +1,32 @@ +package org.vcell.restq; + +import cbit.vcell.modeldb.AdminDBTopLevel; +import cbit.vcell.resource.PropertyLoader; +import io.quarkus.runtime.StartupEvent; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.vcell.restq.db.AgroalConnectionFactory; +import org.vcell.util.DataAccessException; +import org.vcell.util.document.User; + +import java.sql.SQLException; + +@ApplicationScoped +public class StartUpTasks { + private final static Logger logger = LogManager.getLogger(StartUpTasks.class); + + @Inject + AgroalConnectionFactory connectionFactory; + + public void onStartUp(@Observes StartupEvent ev) throws SQLException, DataAccessException { + logger.info("Executing startup tasks"); + + AdminDBTopLevel adminDBTopLevel = new AdminDBTopLevel(connectionFactory); + User vcellSupport = adminDBTopLevel.getVCellSupportUser(true); + PropertyLoader.setProperty(PropertyLoader.vcellSupportId, vcellSupport.getID().toString()); + } + +} diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java index 1c8b3e2eb8..dac126572f 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java @@ -977,6 +977,26 @@ public User.SpecialUser getUser(String userid, boolean bEnableRetry) throws Data } } + public User getVCellSupportUser(boolean bEnableRetry) throws DataAccessException, java.sql.SQLException{ + + Object lock = new Object(); + Connection con = conFactory.getConnection(lock); + try { + return userDB.getVCellSupportUser(con); + } catch(Throwable e){ + lg.error("failure in getUser()", e); + if(bEnableRetry && isBadConnection(con)){ + conFactory.failed(con, lock); + return getVCellSupportUser(false); + } else { + handle_DataAccessException_SQLException(e); + return null; // never gets here; + } + } finally { + conFactory.release(con, lock); + } + } + public User getUserFromSimulationKey(KeyValue simKey, boolean bEnableRetry) throws DataAccessException, java.sql.SQLException{ diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java index 2e659e26c3..98b0f2a65f 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java @@ -169,11 +169,35 @@ public List getUserIdentitiesFromSubjectAndIssuer(Connection con, User userFromDB = new User(userID, new KeyValue(userBD)); UserIdentity userIdentity = UserIdentityTable.table.getUserIdentity(rset, userFromDB, "user_identity_key"); userIdentities.add(userIdentity); + + public User getVCellSupportUser(Connection con) throws SQLException { + Statement stmt; + String sql; + ResultSet rset; + if (lg.isTraceEnabled()) { + lg.trace("UserDbDriver.getIdentitiesFromUser(userid=" + PropertyLoader.VCELL_SUPPORT_USERID + ")"); + } + sql = "SELECT " + UserTable.table.userid.getUnqualifiedColName() + "," + + UserTable.table.id.getUnqualifiedColName() + + " FROM " + userTable.getTableName() + + " WHERE " + UserTable.table.userid.getUnqualifiedColName() + "=" + "'" + PropertyLoader.VCELL_SUPPORT_USERID + "'"; + + System.out.println(sql); + if (lg.isTraceEnabled()) { + lg.trace(sql); + } + stmt = con.createStatement(); + try { + rset = stmt.executeQuery(sql); + if (rset.next()) { + BigDecimal userBD = rset.getBigDecimal(UserTable.table.id.getUnqualifiedColName()); + return new User(PropertyLoader.VCELL_SUPPORT_USERID, new KeyValue(userBD)); + } else { + throw new SQLException("VCell Support not found"); } } finally { stmt.close(); } - return userIdentities; } public List getUserIdentitiesFromUser(Connection con, User user) throws SQLException { From 477c0e67c14aa9e3fa0fa9947bb2cf91b7d40fb7 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 13 Jun 2025 11:28:05 -0400 Subject: [PATCH 02/13] Add User Builder Classes --- .../java/org/vcell/util/document/User.java | 29 ++++++++++++++- .../vcell/modeldb/UserIdentityBuilder.java | 35 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityBuilder.java diff --git a/vcell-core/src/main/java/org/vcell/util/document/User.java b/vcell-core/src/main/java/org/vcell/util/document/User.java index cb46cb9f77..e935b4a85a 100644 --- a/vcell-core/src/main/java/org/vcell/util/document/User.java +++ b/vcell-core/src/main/java/org/vcell/util/document/User.java @@ -10,6 +10,7 @@ package org.vcell.util.document; import java.io.Serializable; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -30,7 +31,8 @@ public class User implements java.io.Serializable, Matchable, Immutable { public enum SPECIAL_CLAIM { admins/*special0*/, powerUsers/*special1*/, - publicationEditors /*publication*/; // users allowed to modify publications + publicationEditors /*publication*/, // users allowed to modify publications + vcellSupport; public static SPECIAL_CLAIM fromDatabase(String databaseString){ if (databaseString.equals(PREVIOUS_DATABASE_VALUE_ADMIN)){ @@ -96,6 +98,8 @@ public boolean isPublisher() { return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.publicationEditors); } + public boolean isVCellSupport() {return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.vcellSupport);} + // @Override // public boolean compareEqual(Matchable obj) { // // TODO Auto-generated method stub @@ -110,6 +114,29 @@ public boolean isPublisher() { // } } + /** + * Builder so that the original classes claim array stays as an unmodified entity. + */ + public static class SpecialUserBuilder{ + private final ArrayList claims = new ArrayList<>(); + private final String userID; + private final KeyValue key; + + public SpecialUserBuilder(String userID, KeyValue key) { + this.userID = userID; + this.key = key; + } + + public SpecialUserBuilder addSpecial(SPECIAL_CLAIM special) { + claims.add(special); + return this; + } + + public SpecialUser build() { + return new SpecialUser(userID,key,claims.toArray(new SPECIAL_CLAIM[]{})); + } + } + /** * User constructor comment. */ diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityBuilder.java b/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityBuilder.java new file mode 100644 index 0000000000..3296c9691a --- /dev/null +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityBuilder.java @@ -0,0 +1,35 @@ +package cbit.vcell.modeldb; + +import org.vcell.util.document.User; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +public class UserIdentityBuilder { + private final BigDecimal id; + private final String subject; + private final String issuer; + private final LocalDateTime insertDate; + private final User.SpecialUserBuilder userBuilder; + + public UserIdentityBuilder(BigDecimal id, User.SpecialUserBuilder specialUserBuilder, + String subject, String issuer, LocalDateTime insertDate){ + this.id = id; + this.subject = subject; + this.issuer = issuer; + this.insertDate = insertDate; + this.userBuilder = specialUserBuilder; + } + + public BigDecimal getId(){ + return id; + } + + public User.SpecialUserBuilder getUserBuilder(){ + return userBuilder; + } + + public UserIdentity build(){ + return new UserIdentity(id, userBuilder.build(), subject, issuer, insertDate); + } +} From 375451031992419470a9489a851ba0b938c1613f Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Fri, 13 Jun 2025 11:28:54 -0400 Subject: [PATCH 03/13] Update User Creation SQL --- .../java/cbit/vcell/modeldb/UserDbDriver.java | 44 ++++++++++++++----- .../cbit/vcell/modeldb/UserIdentityTable.java | 11 ++++- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java index 98b0f2a65f..0a62c094a6 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java @@ -145,14 +145,15 @@ public List getUserIdentitiesFromSubjectAndIssuer(Connection con, lg.trace("UserDbDriver.getUserIdentityFromSubjectAndIssuer(userid=" + subject + ")"); } sql = "SELECT " + UserTable.table.userid.getUnqualifiedColName() + "," + - UserIdentityTable.userRef.getUnqualifiedColName() + "," + - UserIdentityTable.authSubject.getUnqualifiedColName() + "," + - UserIdentityTable.authIssuer.getUnqualifiedColName() + "," + + UserIdentityTable.userRef.getQualifiedColName() + "," + UserIdentityTable.table.id.getQualifiedColName() + " as user_identity_key " + "," + - UserIdentityTable.insertDate.getQualifiedColName() + + UserIdentityTable.insertDate.getQualifiedColName() + "," + + SpecialUsersTable.table.special.getQualifiedColName() + " FROM " + userTable.getTableName() + " JOIN " + UserIdentityTable.table.getTableName() + " ON " + UserIdentityTable.table.userRef.getUnqualifiedColName()+"="+userTable.id.getQualifiedColName() + + " LEFT JOIN " + SpecialUsersTable.table.getTableName() + + " ON " + SpecialUsersTable.table.userRef.getQualifiedColName()+"="+userTable.id.getQualifiedColName() + " WHERE " + UserIdentityTable.authSubject.getUnqualifiedColName() + " = '" + subject + "'" + " AND " + UserIdentityTable.authIssuer.getUnqualifiedColName() + " = '" + issuer + "'"; @@ -160,15 +161,38 @@ public List getUserIdentitiesFromSubjectAndIssuer(Connection con, lg.trace(sql); } stmt = con.createStatement(); - ArrayList userIdentities = new ArrayList<>(); + ArrayList userIdentities = new ArrayList<>(); try { rset = stmt.executeQuery(sql); while (rset.next()) { - BigDecimal userBD = rset.getBigDecimal(UserIdentityTable.userRef.getUnqualifiedColName()); - String userID = rset.getString(UserTable.table.userid.getUnqualifiedColName()); - User userFromDB = new User(userID, new KeyValue(userBD)); - UserIdentity userIdentity = UserIdentityTable.table.getUserIdentity(rset, userFromDB, "user_identity_key"); - userIdentities.add(userIdentity); + BigDecimal userKey = rset.getBigDecimal(UserIdentityTable.userRef.getUnqualifiedColName()); + String claim = rset.getString(SpecialUsersTable.table.special.getUnqualifiedColName()); + + int lastUserAdded = userIdentities.size()-1; + boolean sameUser = !userIdentities.isEmpty() && userIdentities.get(lastUserAdded).getId().equals(userKey); + if (sameUser && claim != null){ + userIdentities.get(lastUserAdded).getUserBuilder().addSpecial(User.SPECIAL_CLAIM.fromDatabase(claim)); + } else{ + String userID = rset.getString(UserTable.table.userid.getUnqualifiedColName()); + User.SpecialUserBuilder builder = new User.SpecialUserBuilder(userID, new KeyValue(userKey)); + if (claim != null){ + builder.addSpecial(User.SPECIAL_CLAIM.fromDatabase(claim)); + } + userIdentities.add(new UserIdentityBuilder(userKey, builder, + subject, issuer, UserIdentityTable.table.getUserIdentityDate(rset))); + } + } + } finally { + stmt.close(); + } + + ArrayList identities = new ArrayList<>(); + for (UserIdentityBuilder userIdentityBuilder : userIdentities) { + identities.add(userIdentityBuilder.build()); + } + + return identities; + } public User getVCellSupportUser(Connection con) throws SQLException { Statement stmt; diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityTable.java index a2caef3f4d..2fbebcbcff 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityTable.java @@ -13,14 +13,12 @@ import cbit.sql.Field; import cbit.sql.Field.SQLDataType; import cbit.sql.Table; -import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; import java.time.LocalDateTime; -import java.util.Date; /** * This type was created in VisualAge. @@ -65,4 +63,13 @@ public UserIdentity getUserIdentity(ResultSet rset, User user, String idColName) return new UserIdentity(id, user, subject, issuer, insertDate); } + + public LocalDateTime getUserIdentityDate(ResultSet rset) throws SQLException { + // + // Format Date + // + java.sql.Date DBDate = rset.getDate(insertDate.getUnqualifiedColName()); + java.sql.Time DBTime = rset.getTime(insertDate.getUnqualifiedColName()); + return LocalDateTime.of(DBDate.toLocalDate(), DBTime.toLocalTime()); + } } From 0ea1c570e2c7e3cde142476d38e51484fc810b02 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 16 Jun 2025 11:13:25 -0400 Subject: [PATCH 04/13] Separate Special User Class --- .../org/vcell/admin/cli/sim/JobAdmin.java | 9 +- .../vcell/admin/cli/sim/SimDataVerifier.java | 2 +- .../org/vcell/rest/VCellApiApplication.java | 3 +- .../vcell/rest/admin/AdminStatsRestlet.java | 5 +- .../org/vcell/rest/rpc/RpcDbServerProxy.java | 4 +- .../rest/server/RestDatabaseService.java | 6 +- .../LocalUserMetaDbServerMessaging.java | 3 +- .../simulation/SimulationWorkspace.java | 6 +- .../SolverTaskDescriptionAdvancedPanel.java | 5 +- .../bootstrap/client/RpcDbServerProxy.java | 4 +- .../cbit/vcell/server/UserMetaDbServer.java | 2 +- .../org/vcell/util/document/SpecialUser.java | 84 ++++++++++++++++++ .../java/org/vcell/util/document/User.java | 88 +------------------ .../org/vcell/util/document/UserTest.java | 4 +- .../SimulationDispatcherEngine.java | 7 +- .../Simulations/SimulationStateMachine.java | 7 +- .../restq/services/AdminRestService.java | 3 +- .../server/dispatcher/SimulationDatabase.java | 5 +- .../dispatcher/SimulationDatabaseDirect.java | 13 ++- .../dispatcher/SimulationDispatcher.java | 9 +- .../SimulationDispatcherEngine.java | 5 +- .../dispatcher/SimulationStateMachine.java | 5 +- .../cbit/vcell/modeldb/AdminDBTopLevel.java | 4 +- .../java/cbit/vcell/modeldb/DBTopLevel.java | 2 +- .../vcell/modeldb/DatabaseServerImpl.java | 2 +- .../java/cbit/vcell/modeldb/DbDriver.java | 22 ++--- .../vcell/modeldb/LocalAdminDbServer.java | 8 +- .../vcell/modeldb/LocalUserMetaDbServer.java | 2 +- .../java/cbit/vcell/modeldb/UserDbDriver.java | 19 ++-- .../vcell/modeldb/UserIdentityBuilder.java | 7 +- .../main/java/org/vcell/auth/JWTUtils.java | 5 +- .../server/dispatcher/MockSimulationDB.java | 18 ++-- .../java/org/vcell/auth/JWTUtilsTest.java | 5 +- 33 files changed, 186 insertions(+), 187 deletions(-) create mode 100644 vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java diff --git a/vcell-admin/src/main/java/org/vcell/admin/cli/sim/JobAdmin.java b/vcell-admin/src/main/java/org/vcell/admin/cli/sim/JobAdmin.java index fac6443626..ca54d8f95e 100644 --- a/vcell-admin/src/main/java/org/vcell/admin/cli/sim/JobAdmin.java +++ b/vcell-admin/src/main/java/org/vcell/admin/cli/sim/JobAdmin.java @@ -22,6 +22,7 @@ import org.apache.logging.log4j.Logger; import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import org.vcell.util.document.VCellServerID; import org.vcell.util.exe.ExecutableException; @@ -86,11 +87,11 @@ public void run(HtcProxy.PartitionStatistics partitionStatistics, int userQuotaO public User[] getQuotaExemptUsers() throws SQLException, DataAccessException { ArrayList adminUserList = new ArrayList(); - TreeMap> specialUsers = simulationDatabase.getSpecialUsers(); - final Iterator iterator = specialUsers.keySet().iterator(); + TreeMap> specialUsers = simulationDatabase.getSpecialUsers(); + final Iterator iterator = specialUsers.keySet().iterator(); while(iterator.hasNext()) { - final User.SPECIAL_CLAIM next = iterator.next(); - if(next == User.SPECIAL_CLAIM.admins) {//Admin Users + final SpecialUser.SPECIAL_CLAIM next = iterator.next(); + if(next == SpecialUser.SPECIAL_CLAIM.admins) {//Admin Users final Iterator iter = specialUsers.get(next).keySet().iterator(); while(iter.hasNext()) { adminUserList.add(iter.next()); diff --git a/vcell-admin/src/main/java/org/vcell/admin/cli/sim/SimDataVerifier.java b/vcell-admin/src/main/java/org/vcell/admin/cli/sim/SimDataVerifier.java index 4b238bd819..e81a33db5e 100644 --- a/vcell-admin/src/main/java/org/vcell/admin/cli/sim/SimDataVerifier.java +++ b/vcell-admin/src/main/java/org/vcell/admin/cli/sim/SimDataVerifier.java @@ -97,7 +97,7 @@ private List getUsers(String singleUsername, String startingUsername, bool throws DataAccessException, SQLException { if (singleUsername != null){ - User.SpecialUser user = adminDbTopLevel.getUser(singleUsername, true); + SpecialUser user = adminDbTopLevel.getUser(singleUsername, true); if (user == null){ throw new RuntimeException("failed to find user "+singleUsername); } diff --git a/vcell-api/src/main/java/org/vcell/rest/VCellApiApplication.java b/vcell-api/src/main/java/org/vcell/rest/VCellApiApplication.java index f0256cd539..c086cfdaf8 100644 --- a/vcell-api/src/main/java/org/vcell/rest/VCellApiApplication.java +++ b/vcell-api/src/main/java/org/vcell/rest/VCellApiApplication.java @@ -35,6 +35,7 @@ import org.vcell.rest.users.*; import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import java.io.File; @@ -396,7 +397,7 @@ public AdminService getAdminService() { return this.adminService; } - public User.SPECIAL_CLAIM[] getSpecialClaims(ApiAccessToken apiAccessToken) throws DataAccessException { + public SpecialUser.SPECIAL_CLAIM[] getSpecialClaims(ApiAccessToken apiAccessToken) throws DataAccessException { User user = apiAccessToken.getUser(); return restDatabaseService.getSpecialClaims(user); } diff --git a/vcell-api/src/main/java/org/vcell/rest/admin/AdminStatsRestlet.java b/vcell-api/src/main/java/org/vcell/rest/admin/AdminStatsRestlet.java index fabf33ecce..0cbea17467 100644 --- a/vcell-api/src/main/java/org/vcell/rest/admin/AdminStatsRestlet.java +++ b/vcell-api/src/main/java/org/vcell/rest/admin/AdminStatsRestlet.java @@ -14,6 +14,7 @@ import org.vcell.rest.VCellApiApplication; import org.vcell.rest.rpc.RpcRestlet; import org.vcell.rest.server.RestDatabaseService; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import java.util.Arrays; @@ -47,8 +48,8 @@ public void handle(Request req, Response response) { return; } User user = application.getVCellUser(req.getChallengeResponse(), VCellApiApplication.AuthenticationPolicy.prohibitInvalidCredentials); - User.SPECIAL_CLAIM[] mySpecials = application.getSpecialClaims(token); - if (mySpecials==null || !Arrays.stream(mySpecials).anyMatch(s -> (s == User.SPECIAL_CLAIM.admins))) { + SpecialUser.SPECIAL_CLAIM[] mySpecials = application.getSpecialClaims(token); + if (mySpecials==null || !Arrays.stream(mySpecials).anyMatch(s -> (s == SpecialUser.SPECIAL_CLAIM.admins))) { response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED); response.setEntity("

account '"+user.getName()+"' has insufficient privilege

" + "

click here to log out

", diff --git a/vcell-api/src/main/java/org/vcell/rest/rpc/RpcDbServerProxy.java b/vcell-api/src/main/java/org/vcell/rest/rpc/RpcDbServerProxy.java index 1a404e5da3..c7d8953b3c 100644 --- a/vcell-api/src/main/java/org/vcell/rest/rpc/RpcDbServerProxy.java +++ b/vcell-api/src/main/java/org/vcell/rest/rpc/RpcDbServerProxy.java @@ -28,8 +28,8 @@ public RpcDbServerProxy(UserLoginInfo userLoginInfo, VCMessageSession vcMessageS super(userLoginInfo, vcMessageSession, VCellQueue.DbRequestQueue); } -public TreeMap> getSpecialUsers() throws DataAccessException{ - return (TreeMap>)rpc("getSpecialUsers",new Object[0]); +public TreeMap> getSpecialUsers() throws DataAccessException{ + return (TreeMap>)rpc("getSpecialUsers",new Object[0]); } public org.vcell.util.document.VCDocumentInfo curate(CurateSpec curateSpec) throws DataAccessException, ObjectNotFoundException { diff --git a/vcell-api/src/main/java/org/vcell/rest/server/RestDatabaseService.java b/vcell-api/src/main/java/org/vcell/rest/server/RestDatabaseService.java index a50033c149..1a262d836c 100644 --- a/vcell-api/src/main/java/org/vcell/rest/server/RestDatabaseService.java +++ b/vcell-api/src/main/java/org/vcell/rest/server/RestDatabaseService.java @@ -73,8 +73,8 @@ public RestDatabaseService(DatabaseServerImpl databaseServerImpl, LocalAdminDbSe } - public User.SPECIAL_CLAIM[] getSpecialClaims(User user) throws DataAccessException { - User.SpecialUser userWithClaims = localAdminDbServer.getUser(user.getName()); + public SpecialUser.SPECIAL_CLAIM[] getSpecialClaims(User user) throws DataAccessException { + SpecialUser userWithClaims = localAdminDbServer.getUser(user.getName()); return userWithClaims.getMySpecials(); } @@ -112,7 +112,7 @@ public String getBasicStatistics() throws SQLException, DataAccessException{ return databaseServerImpl.getAdminDBTopLevel().getBasicStatistics(); } - public TreeMap> getSpecialUsers(User user) throws DataAccessException{ + public TreeMap> getSpecialUsers(User user) throws DataAccessException{ return databaseServerImpl.getSpecialUsers(user); } diff --git a/vcell-apiclient/src/main/java/org/vcell/api/messaging/LocalUserMetaDbServerMessaging.java b/vcell-apiclient/src/main/java/org/vcell/api/messaging/LocalUserMetaDbServerMessaging.java index 0603047d97..41f6b2ac2d 100644 --- a/vcell-apiclient/src/main/java/org/vcell/api/messaging/LocalUserMetaDbServerMessaging.java +++ b/vcell-apiclient/src/main/java/org/vcell/api/messaging/LocalUserMetaDbServerMessaging.java @@ -33,6 +33,7 @@ import org.vcell.util.document.*; import org.vcell.util.document.ExternalDataIdentifier; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import java.rmi.RemoteException; @@ -55,7 +56,7 @@ public LocalUserMetaDbServerMessaging(UserLoginInfo userLoginInfo, RpcSender rpc this.vCellApiClient = vCellApiClient; } -public TreeMap> getSpecialUsers() throws DataAccessException{ +public TreeMap> getSpecialUsers() throws DataAccessException{ try { return dbServerProxy.getSpecialUsers(); } catch (DataAccessException e) { diff --git a/vcell-client/src/main/java/cbit/vcell/client/desktop/simulation/SimulationWorkspace.java b/vcell-client/src/main/java/cbit/vcell/client/desktop/simulation/SimulationWorkspace.java index e7bdd6be9b..969b2c788d 100644 --- a/vcell-client/src/main/java/cbit/vcell/client/desktop/simulation/SimulationWorkspace.java +++ b/vcell-client/src/main/java/cbit/vcell/client/desktop/simulation/SimulationWorkspace.java @@ -32,8 +32,8 @@ import org.vcell.chombo.ChomboMeshValidator.ChomboMeshRecommendation; import org.vcell.util.PropertyChangeListenerProxyVCell; import org.vcell.util.document.PropertyConstants; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; -import org.vcell.util.document.User.SPECIAL_CLAIM; import org.vcell.util.gui.DialogUtils; import javax.swing.*; @@ -811,8 +811,8 @@ public void run(Hashtable hashTable) throws Exception { boolean bCheckLimits = true; try { User loginUser = VCellClient.getInstance().getClientServerManager().getUser(); - TreeMap> specialUsers = VCellClient.getInstance().getClientServerManager().getUserMetaDbServer().getSpecialUsers(); - TreeMap powerUsers = specialUsers.get(SPECIAL_CLAIM.powerUsers); + TreeMap> specialUsers = VCellClient.getInstance().getClientServerManager().getUserMetaDbServer().getSpecialUsers(); + TreeMap powerUsers = specialUsers.get(SpecialUser.SPECIAL_CLAIM.powerUsers); if(powerUsers != null && powerUsers.containsKey(loginUser)) { bCheckLimits = false; } diff --git a/vcell-client/src/main/java/cbit/vcell/solver/ode/gui/SolverTaskDescriptionAdvancedPanel.java b/vcell-client/src/main/java/cbit/vcell/solver/ode/gui/SolverTaskDescriptionAdvancedPanel.java index 811e1781cd..a157b736a4 100644 --- a/vcell-client/src/main/java/cbit/vcell/solver/ode/gui/SolverTaskDescriptionAdvancedPanel.java +++ b/vcell-client/src/main/java/cbit/vcell/solver/ode/gui/SolverTaskDescriptionAdvancedPanel.java @@ -33,6 +33,7 @@ import org.vcell.chombo.gui.ChomboTimeBoundsPanel; import org.vcell.solver.nfsim.gui.NFSimSimulationOptionsPanel; import org.vcell.solver.smoldyn.gui.SmoldynSimulationOptionsPanel; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import org.vcell.util.gui.CollapsiblePanel; import org.vcell.util.gui.DialogUtils; @@ -1117,8 +1118,8 @@ private void refresh() { public void run(Hashtable hashTable) throws Exception { try { User loginUser = VCellClient.getInstance().getClientServerManager().getUser(); - TreeMap> specialUsers = VCellClient.getInstance().getClientServerManager().getUserMetaDbServer().getSpecialUsers(); - TreeMap powerUsers = specialUsers.get(User.SPECIAL_CLAIM.powerUsers); + TreeMap> specialUsers = VCellClient.getInstance().getClientServerManager().getUserMetaDbServer().getSpecialUsers(); + TreeMap powerUsers = specialUsers.get(SpecialUser.SPECIAL_CLAIM.powerUsers); if(powerUsers != null && powerUsers.containsKey(loginUser)) { hashTable.put(TIMEOUT_DISABLE, true); } diff --git a/vcell-core/src/main/java/cbit/vcell/message/server/bootstrap/client/RpcDbServerProxy.java b/vcell-core/src/main/java/cbit/vcell/message/server/bootstrap/client/RpcDbServerProxy.java index 8bc6fe19ca..672ec9f182 100644 --- a/vcell-core/src/main/java/cbit/vcell/message/server/bootstrap/client/RpcDbServerProxy.java +++ b/vcell-core/src/main/java/cbit/vcell/message/server/bootstrap/client/RpcDbServerProxy.java @@ -28,8 +28,8 @@ public RpcDbServerProxy(UserLoginInfo userLoginInfo, RpcSender rpcSender) { super(userLoginInfo, rpcSender, VCellQueue.DbRequestQueue); } -public TreeMap> getSpecialUsers() throws DataAccessException{ - return (TreeMap>)rpc("getSpecialUsers",new Object[0]); +public TreeMap> getSpecialUsers() throws DataAccessException{ + return (TreeMap>)rpc("getSpecialUsers",new Object[0]); } public org.vcell.util.document.VCDocumentInfo curate(CurateSpec curateSpec) throws DataAccessException, ObjectNotFoundException { diff --git a/vcell-core/src/main/java/cbit/vcell/server/UserMetaDbServer.java b/vcell-core/src/main/java/cbit/vcell/server/UserMetaDbServer.java index 486f45e83a..2f0f519eed 100644 --- a/vcell-core/src/main/java/cbit/vcell/server/UserMetaDbServer.java +++ b/vcell-core/src/main/java/cbit/vcell/server/UserMetaDbServer.java @@ -36,7 +36,7 @@ */ public interface UserMetaDbServer { -TreeMap> getSpecialUsers() throws DataAccessException; +TreeMap> getSpecialUsers() throws DataAccessException; /** * Insert the method's description here. diff --git a/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java b/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java new file mode 100644 index 0000000000..9773c99e82 --- /dev/null +++ b/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java @@ -0,0 +1,84 @@ +package org.vcell.util.document; + +import org.vcell.util.Immutable; +import org.vcell.util.Matchable; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; + +public class SpecialUser extends User implements Serializable, Matchable, Immutable { + private final static String PREVIOUS_DATABASE_VALUE_ADMIN = "special0"; + private final static String PREVIOUS_DATABASE_VALUE_POWERUSER = "special1"; + private final static String PREVIOUS_DATABASE_VALUE_PUBLICATION = "publication"; + + public enum SPECIAL_CLAIM { + admins/*special0*/, + powerUsers/*special1*/, + publicationEditors /*publication*/, // users allowed to modify publications + vcellSupport; + + public static SPECIAL_CLAIM fromDatabase(String databaseString){ + if (databaseString.equals(PREVIOUS_DATABASE_VALUE_ADMIN)){ + return admins; + } + if (databaseString.equals(PREVIOUS_DATABASE_VALUE_POWERUSER)){ + return powerUsers; + } + if (databaseString.equals(PREVIOUS_DATABASE_VALUE_PUBLICATION)){ + return publicationEditors; + } + return SPECIAL_CLAIM.valueOf(databaseString); + } + + public String toDatabaseString(){ + return name(); + } + };//Must match a name 'special' column of 'vc_specialusers'// table + + protected SPECIAL_CLAIM[] mySpecials; + + public SpecialUser(String userid, KeyValue key, SPECIAL_CLAIM[] mySpecials) { + super(userid, key); + this.mySpecials = mySpecials; + } + + public SPECIAL_CLAIM[] getMySpecials() { + return mySpecials; + } + + public boolean isAdmin() { + return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.admins); + } + + public boolean isPublisher() { + return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.publicationEditors); + } + + public boolean isVCellSupport() { + return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.vcellSupport); + } + + /** + * Builder so that the original classes claim array stays as an unmodified entity. + */ + public static class SpecialUserBuilder{ + private final ArrayList claims = new ArrayList<>(); + private final String userID; + private final KeyValue key; + + public SpecialUserBuilder(String userID, KeyValue key) { + this.userID = userID; + this.key = key; + } + + public SpecialUserBuilder addSpecial(SPECIAL_CLAIM special) { + claims.add(special); + return this; + } + + public org.vcell.util.document.SpecialUser build() { + return new SpecialUser(userID,key,claims.toArray(new SPECIAL_CLAIM[]{})); + } + } +} diff --git a/vcell-core/src/main/java/org/vcell/util/document/User.java b/vcell-core/src/main/java/org/vcell/util/document/User.java index e935b4a85a..f63a2c2790 100644 --- a/vcell-core/src/main/java/org/vcell/util/document/User.java +++ b/vcell-core/src/main/java/org/vcell/util/document/User.java @@ -11,11 +11,11 @@ package org.vcell.util.document; import java.io.Serializable; import java.util.ArrayList; -import java.util.Arrays; import java.util.Comparator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.vcell.util.Immutable; import org.vcell.util.Matchable; @@ -24,34 +24,6 @@ */ @SuppressWarnings("serial") public class User implements java.io.Serializable, Matchable, Immutable { - private final static String PREVIOUS_DATABASE_VALUE_ADMIN = "special0"; - private final static String PREVIOUS_DATABASE_VALUE_POWERUSER = "special1"; - private final static String PREVIOUS_DATABASE_VALUE_PUBLICATION = "publication"; - - public enum SPECIAL_CLAIM { - admins/*special0*/, - powerUsers/*special1*/, - publicationEditors /*publication*/, // users allowed to modify publications - vcellSupport; - - public static SPECIAL_CLAIM fromDatabase(String databaseString){ - if (databaseString.equals(PREVIOUS_DATABASE_VALUE_ADMIN)){ - return admins; - } - if (databaseString.equals(PREVIOUS_DATABASE_VALUE_POWERUSER)){ - return powerUsers; - } - if (databaseString.equals(PREVIOUS_DATABASE_VALUE_PUBLICATION)){ - return publicationEditors; - } - return SPECIAL_CLAIM.valueOf(databaseString); - } - - public String toDatabaseString(){ - return name(); - } - };//Must match a name 'special' column of 'vc_specialusers'// table - @JsonProperty private String userName = null; @JsonProperty @@ -59,7 +31,6 @@ public String toDatabaseString(){ public static final String VCellTestAccountName = "vcelltestaccount"; - public static final User tempUser = new User("temp",new KeyValue("123")); public static final String VCELL_GUEST_NAME = "vcellguest"; public static final User VCELL_GUEST = new User(VCELL_GUEST_NAME,new KeyValue("140220477")); @@ -80,63 +51,6 @@ public String toSubject() { return userName+":"+key; } - public static class SpecialUser extends User implements Serializable, Matchable, Immutable{ - private SPECIAL_CLAIM[] mySpecials; - public SpecialUser(String userid, KeyValue key,SPECIAL_CLAIM[] mySpecials) { - super(userid, key); - this.mySpecials = mySpecials; - } - public SPECIAL_CLAIM[] getMySpecials() { - return mySpecials; - } - - public boolean isAdmin() { - return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.admins); - } - - public boolean isPublisher() { - return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.publicationEditors); - } - - public boolean isVCellSupport() {return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.vcellSupport);} - -// @Override -// public boolean compareEqual(Matchable obj) { -// // TODO Auto-generated method stub -// if(obj == this) { -// return true; -// } -// boolean superCompare = super.compareEqual(obj); -// if(obj instanceof SpecialUser) { -// return superCompare && Compare.isEqualOrNullStrict(((SpecialUser)obj).getMySpecials(), getMySpecials()); -// } -// return superCompare; -// } - } - - /** - * Builder so that the original classes claim array stays as an unmodified entity. - */ - public static class SpecialUserBuilder{ - private final ArrayList claims = new ArrayList<>(); - private final String userID; - private final KeyValue key; - - public SpecialUserBuilder(String userID, KeyValue key) { - this.userID = userID; - this.key = key; - } - - public SpecialUserBuilder addSpecial(SPECIAL_CLAIM special) { - claims.add(special); - return this; - } - - public SpecialUser build() { - return new SpecialUser(userID,key,claims.toArray(new SPECIAL_CLAIM[]{})); - } - } - /** * User constructor comment. */ diff --git a/vcell-core/src/test/java/org/vcell/util/document/UserTest.java b/vcell-core/src/test/java/org/vcell/util/document/UserTest.java index 8989d0dec5..672342920e 100644 --- a/vcell-core/src/test/java/org/vcell/util/document/UserTest.java +++ b/vcell-core/src/test/java/org/vcell/util/document/UserTest.java @@ -13,9 +13,9 @@ public class UserTest { @Test public void publisherTest( ) { - User.SpecialUser u = new User.SpecialUser("schaff", testKey( ), new User.SPECIAL_CLAIM[] {User.SPECIAL_CLAIM.publicationEditors}); + SpecialUser u = new SpecialUser("schaff", testKey( ), new SpecialUser.SPECIAL_CLAIM[] {SpecialUser.SPECIAL_CLAIM.publicationEditors}); Assertions.assertTrue(u.isPublisher()); - u = new User.SpecialUser("fido", testKey( ), new User.SPECIAL_CLAIM[]{}); + u = new SpecialUser("fido", testKey( ), new SpecialUser.SPECIAL_CLAIM[]{}); assertFalse(u.isPublisher()); } @Test diff --git a/vcell-rest/src/main/java/org/vcell/restq/Simulations/SimulationDispatcherEngine.java b/vcell-rest/src/main/java/org/vcell/restq/Simulations/SimulationDispatcherEngine.java index 1a1c9288db..6ef0cd1178 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/Simulations/SimulationDispatcherEngine.java +++ b/vcell-rest/src/main/java/org/vcell/restq/Simulations/SimulationDispatcherEngine.java @@ -3,9 +3,7 @@ import cbit.rmi.event.WorkerEvent; import cbit.vcell.message.VCMessageSession; import cbit.vcell.message.VCMessagingException; -import org.vcell.restq.Simulations.StatusMessage; import cbit.vcell.message.server.dispatcher.SimulationDatabase; -import org.vcell.restq.Simulations.SimulationStateMachine; import cbit.vcell.server.SimulationJobStatus; import cbit.vcell.server.UpdateSynchronizationException; import cbit.vcell.solver.Simulation; @@ -16,6 +14,7 @@ import org.apache.logging.log4j.Logger; import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import org.vcell.util.document.VCellServerID; @@ -60,8 +59,8 @@ public void onDispatch(Simulation simulation, SimulationJobStatus simJobStatus, public ArrayList onStartRequest(VCSimulationIdentifier vcSimID, User user, int simulationScanCount, SimulationDatabase simulationDatabase, VCMessageSession session, VCMessageSession dispatcherQueueSession) throws VCMessagingException, DataAccessException, SQLException { KeyValue simKey = vcSimID.getSimulationKey(); - User.SpecialUser myUser = simulationDatabase.getUser(user.getName()); - boolean isAdmin = Arrays.asList(myUser.getMySpecials()).contains(User.SPECIAL_CLAIM.admins); + SpecialUser myUser = simulationDatabase.getUser(user.getName()); + boolean isAdmin = Arrays.asList(myUser.getMySpecials()).contains(SpecialUser.SPECIAL_CLAIM.admins); SimulationInfo simulationInfo = null; SimulationJobStatus simJobStatus = null; diff --git a/vcell-rest/src/main/java/org/vcell/restq/Simulations/SimulationStateMachine.java b/vcell-rest/src/main/java/org/vcell/restq/Simulations/SimulationStateMachine.java index 1608b025c9..03973a7378 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/Simulations/SimulationStateMachine.java +++ b/vcell-rest/src/main/java/org/vcell/restq/Simulations/SimulationStateMachine.java @@ -5,7 +5,6 @@ import cbit.vcell.message.*; import cbit.vcell.message.messages.MessageConstants; import cbit.vcell.message.messages.SimulationTaskMessage; -import org.vcell.restq.Simulations.StatusMessage; import cbit.vcell.message.messages.WorkerEventMessage; import cbit.vcell.message.server.dispatcher.SimulationDatabase; import cbit.vcell.message.server.htc.HtcProxy; @@ -18,11 +17,11 @@ import org.apache.logging.log4j.Logger; import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import org.vcell.util.document.VCellServerID; import java.sql.SQLException; -import java.time.ZoneId; import java.util.Arrays; import java.util.Date; @@ -430,9 +429,9 @@ public synchronized void onDispatch(Simulation simulation, SimulationJobStatus o //has checked the 'timeoutDisabledCheckBox' in SolverTaskDescriptionAdvancedPanel on the client-side GUI boolean isPowerUser = simulation.getSolverTaskDescription().isTimeoutDisabled();//Set from GUI if(isPowerUser) {//Check if user allowed to be power user for 'special1' long running sims (see User.SPECIALS and vc_specialusers table) - User.SpecialUser myUser = simulationDatabase.getUser(simulation.getVersion().getOwner().getName()); + SpecialUser myUser = simulationDatabase.getUser(simulation.getVersion().getOwner().getName()); //'powerUsers' (previously called 'special1') assigned to users by request to allow long running sims - isPowerUser = isPowerUser && Arrays.asList(myUser.getMySpecials()).contains(User.SPECIAL_CLAIM.powerUsers); + isPowerUser = isPowerUser && Arrays.asList(myUser.getMySpecials()).contains(SpecialUser.SPECIAL_CLAIM.powerUsers); } SimulationTask simulationTask = new SimulationTask(new SimulationJob(simulation, jobIndex, fieldDataIdentifierSpecs), taskID,null,isPowerUser); diff --git a/vcell-rest/src/main/java/org/vcell/restq/services/AdminRestService.java b/vcell-rest/src/main/java/org/vcell/restq/services/AdminRestService.java index 72e6cf2074..199bd1dbce 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/services/AdminRestService.java +++ b/vcell-rest/src/main/java/org/vcell/restq/services/AdminRestService.java @@ -6,6 +6,7 @@ import org.vcell.restq.db.AgroalConnectionFactory; import org.vcell.restq.errors.exceptions.PermissionWebException; import org.vcell.util.DataAccessException; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import java.sql.SQLException; @@ -25,7 +26,7 @@ public AdminRestService(AgroalConnectionFactory agroalConnectionFactory) throws } public String getUsageSummaryHtml(User vcUser) throws DataAccessException, SQLException, PermissionWebException { - User.SpecialUser specialUser = adminDBTopLevel.getUser(vcUser.getName(), true); + SpecialUser specialUser = adminDBTopLevel.getUser(vcUser.getName(), true); if (specialUser.isAdmin()){ return adminDBTopLevel.getBasicStatistics(); }else{ diff --git a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDatabase.java b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDatabase.java index 81e65363be..81dab7e37f 100644 --- a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDatabase.java +++ b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDatabase.java @@ -9,6 +9,7 @@ import org.vcell.util.DataAccessException; import org.vcell.util.ObjectNotFoundException; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import org.vcell.util.document.VCellServerID; @@ -54,9 +55,9 @@ public interface SimulationDatabase { public Set getUnreferencedSimulations() throws SQLException; - public User.SpecialUser getUser(String username) throws DataAccessException, SQLException; + public SpecialUser getUser(String username) throws DataAccessException, SQLException; - public TreeMap> getSpecialUsers() throws DataAccessException, SQLException; + public TreeMap> getSpecialUsers() throws DataAccessException, SQLException; public SimulationInfo getSimulationInfo(User user, KeyValue simKey) throws ObjectNotFoundException, DataAccessException; diff --git a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDatabaseDirect.java b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDatabaseDirect.java index 66289fc043..1eeecaeacb 100644 --- a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDatabaseDirect.java +++ b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDatabaseDirect.java @@ -24,10 +24,7 @@ import org.vcell.util.BigString; import org.vcell.util.DataAccessException; 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.VCellServerID; +import org.vcell.util.document.*; import java.sql.SQLException; import java.util.*; @@ -39,7 +36,7 @@ public class SimulationDatabaseDirect implements SimulationDatabase { private AdminDBTopLevel adminDbTopLevel = null; private DatabaseServerImpl databaseServerImpl = null; private Map simFieldDataIDMap = Collections.synchronizedMap(new HashMap()); - private Map userMap = Collections.synchronizedMap(new HashMap<>()); + private Map userMap = Collections.synchronizedMap(new HashMap<>()); private SimpleJobStatusCache cache = null; public static class SimJobStatusKey { @@ -301,8 +298,8 @@ public Set getUnreferencedSimulations() throws SQLException{ } @Override - public User.SpecialUser getUser(String username) throws DataAccessException, SQLException { - User.SpecialUser user = null; + public SpecialUser getUser(String username) throws DataAccessException, SQLException { + SpecialUser user = null; synchronized(userMap) { user = userMap.get(username); @@ -323,7 +320,7 @@ public User.SpecialUser getUser(String username) throws DataAccessException, SQL return user; } - public TreeMap> getSpecialUsers() throws DataAccessException, SQLException{ + public TreeMap> getSpecialUsers() throws DataAccessException, SQLException{ return databaseServerImpl.getSpecialUsers(null); } diff --git a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDispatcher.java b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDispatcher.java index d612019a4d..5c44bf7111 100644 --- a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDispatcher.java +++ b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDispatcher.java @@ -48,6 +48,7 @@ import org.vcell.util.DataAccessException; import org.vcell.util.PermissionException; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import org.vcell.util.document.VCellServerID; import org.vcell.util.exe.ExecutableException; @@ -223,11 +224,11 @@ public SimpleJobStatus[] getSimpleJobStatus(User user, SimpleJobStatusQuerySpec private void reloadSpecialUsers() { try { ArrayList adminUserList = new ArrayList(); - TreeMap> specialUsers = simulationDatabase.getSpecialUsers(); - final Iterator iterator = specialUsers.keySet().iterator(); + TreeMap> specialUsers = simulationDatabase.getSpecialUsers(); + final Iterator iterator = specialUsers.keySet().iterator(); while(iterator.hasNext()) { - final User.SPECIAL_CLAIM next = iterator.next(); - if(next == User.SPECIAL_CLAIM.admins) {//Admin Users + final SpecialUser.SPECIAL_CLAIM next = iterator.next(); + if(next == SpecialUser.SPECIAL_CLAIM.admins) {//Admin Users final Iterator iter = specialUsers.get(next).keySet().iterator(); while(iter.hasNext()) { adminUserList.add(iter.next()); diff --git a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDispatcherEngine.java b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDispatcherEngine.java index 1af3550fc9..da4c5399aa 100644 --- a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDispatcherEngine.java +++ b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationDispatcherEngine.java @@ -15,6 +15,7 @@ import org.apache.logging.log4j.Logger; import org.vcell.util.DataAccessException; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import org.vcell.util.document.VCellServerID; @@ -70,8 +71,8 @@ public void onDispatch(Simulation simulation, SimulationJobStatus simJobStatus, public ArrayList onStartRequest(VCSimulationIdentifier vcSimID, User user, int simulationScanCount, SimulationDatabase simulationDatabase, VCMessageSession session, VCMessageSession dispatcherQueueSession) throws VCMessagingException, DataAccessException, SQLException { KeyValue simKey = vcSimID.getSimulationKey(); - User.SpecialUser myUser = simulationDatabase.getUser(user.getName()); - boolean isAdmin = Arrays.asList(myUser.getMySpecials()).contains(User.SPECIAL_CLAIM.admins); + SpecialUser myUser = simulationDatabase.getUser(user.getName()); + boolean isAdmin = Arrays.asList(myUser.getMySpecials()).contains(SpecialUser.SPECIAL_CLAIM.admins); SimulationInfo simulationInfo = null; SimulationJobStatus simJobStatus = null; diff --git a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationStateMachine.java b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationStateMachine.java index 1f318017d6..07204c2d5d 100644 --- a/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationStateMachine.java +++ b/vcell-server/src/main/java/cbit/vcell/message/server/dispatcher/SimulationStateMachine.java @@ -19,6 +19,7 @@ import cbit.vcell.server.SimulationJobStatus.SchedulerStatus; import cbit.vcell.server.SimulationJobStatus.SimulationQueueID; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import org.vcell.util.document.VCellServerID; @@ -455,9 +456,9 @@ public synchronized void onDispatch(Simulation simulation, SimulationJobStatus o //has checked the 'timeoutDisabledCheckBox' in SolverTaskDescriptionAdvancedPanel on the client-side GUI boolean isPowerUser = simulation.getSolverTaskDescription().isTimeoutDisabled();//Set from GUI if(isPowerUser) {//Check if user allowed to be power user for 'special1' long running sims (see User.SPECIALS and vc_specialusers table) - User.SpecialUser myUser = simulationDatabase.getUser(simulation.getVersion().getOwner().getName()); + SpecialUser myUser = simulationDatabase.getUser(simulation.getVersion().getOwner().getName()); //'powerUsers' (previously called 'special1') assigned to users by request to allow long running sims - isPowerUser = isPowerUser && Arrays.asList(myUser.getMySpecials()).contains(User.SPECIAL_CLAIM.powerUsers); + isPowerUser = isPowerUser && Arrays.asList(myUser.getMySpecials()).contains(SpecialUser.SPECIAL_CLAIM.powerUsers); } SimulationTask simulationTask = new SimulationTask(new SimulationJob(simulation, jobIndex, fieldDataIdentifierSpecs), taskID,null,isPowerUser); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java index dac126572f..b35dad648b 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java @@ -275,7 +275,7 @@ public record DbUsageSummary( public record DbUserSimCount(String userid, KeyValue userkey, String firstname, String lastname, String email, NotifyValue notify_value, int simCount) {} public record DbUsersRegisteredStats(int last1Week, int last1Month, int last3Months, int last6Months, int last12Months) {} - public synchronized DbUsageSummary getUsageSummary(User.SpecialUser user) throws SQLException, DataAccessException{ + public synchronized DbUsageSummary getUsageSummary(SpecialUser user) throws SQLException, DataAccessException{ if (!user.isAdmin()){ throw new PermissionException("not authorized"); } @@ -957,7 +957,7 @@ public ApiClient getApiClient(String clientId, boolean bEnableRetry) throws SQLE } - public User.SpecialUser getUser(String userid, boolean bEnableRetry) throws DataAccessException, java.sql.SQLException{ + public SpecialUser getUser(String userid, boolean bEnableRetry) throws DataAccessException, java.sql.SQLException{ Object lock = new Object(); Connection con = conFactory.getConnection(lock); 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 85db91c3b8..4b5b183172 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DBTopLevel.java @@ -979,7 +979,7 @@ VCImage getVCImage(QueryHashtable dbc, User user, KeyValue key, boolean bCheckPe * @return cbit.vcell.modeldb.VCInfoContainer * @param user cbit.vcell.server.User */ -TreeMap> getSpecialUsers(User user,boolean bEnableRetry) throws DataAccessException, java.sql.SQLException{ +TreeMap> getSpecialUsers(User user,boolean bEnableRetry) throws DataAccessException, java.sql.SQLException{ Object lock = new Object(); Connection con = conFactory.getConnection(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 e03196e664..46e752b331 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabaseServerImpl.java @@ -96,7 +96,7 @@ public DatabaseServerImpl(ConnectionFactory conFactory, KeyFactory keyFactory) } } -public TreeMap> getSpecialUsers(User user) throws DataAccessException{ +public TreeMap> getSpecialUsers(User user) throws DataAccessException{ try { return dbTop.getSpecialUsers(user,true); } catch (Exception e) { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DbDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DbDriver.java index 462fe5f0b1..9aef1cb412 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DbDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DbDriver.java @@ -75,8 +75,8 @@ public DbDriver(DatabaseSyntax dbSyntax, KeyFactory keyFactory){ } public static void publishDirectly(Connection con, KeyValue[] publishTheseBiomodels, KeyValue[] publishTheseMathmodels, User user, DatabaseSyntax databaseSyntax) throws SQLException, DataAccessException{ - TreeMap> specialUsers = getSpecialUsers(user, con, databaseSyntax); - TreeMap usersAllowedToModifyPublications = specialUsers.get(User.SPECIAL_CLAIM.publicationEditors); + TreeMap> specialUsers = getSpecialUsers(user, con, databaseSyntax); + TreeMap usersAllowedToModifyPublications = specialUsers.get(SpecialUser.SPECIAL_CLAIM.publicationEditors); if(usersAllowedToModifyPublications == null || !usersAllowedToModifyPublications.containsKey(user)){ throw new DataAccessException("User " + user.getName() + " does not have permission to publish directly"); } @@ -104,13 +104,13 @@ public static void publishDirectly(Connection con, KeyValue[] publishTheseBiomod } } - public static void checkRolePermission(Connection con, User user, User.SPECIAL_CLAIM claim, String permissionText, DatabaseSyntax databaseSyntax) throws SQLException,DataAccessException{ - if (user instanceof User.SpecialUser specialUser){ + public static void checkRolePermission(Connection con, User user, SpecialUser.SPECIAL_CLAIM claim, String permissionText, DatabaseSyntax databaseSyntax) throws SQLException,DataAccessException{ + if (user instanceof SpecialUser specialUser){ if (!Arrays.asList(specialUser.getMySpecials()).contains(claim)){ throw new PermissionException("User "+user.getName()+" does not have permission to " + permissionText); } }else { - TreeMap> specialUsers = getSpecialUsers(user, con, databaseSyntax); + TreeMap> specialUsers = getSpecialUsers(user, con, databaseSyntax); TreeMap usersAllowedToModifyPublications = specialUsers.get(claim); if (usersAllowedToModifyPublications == null || !usersAllowedToModifyPublications.containsKey(user)) { throw new PermissionException("User " + user.getName() + " does not have permission to " + permissionText); @@ -121,7 +121,7 @@ public static void checkRolePermission(Connection con, User user, User.SPECIAL_C public static KeyValue savePublicationRep(Connection con,PublicationRep publicationRep,User user,KeyFactory keyFactory,DatabaseSyntax databaseSyntax) throws SQLException, DataAccessException{ KeyValue pubID = null; - checkRolePermission(con, user, User.SPECIAL_CLAIM.publicationEditors, "edit publications", databaseSyntax); + checkRolePermission(con, user, SpecialUser.SPECIAL_CLAIM.publicationEditors, "edit publications", databaseSyntax); final String YMD_FORMAT_STRING = "yyyy-MM-dd"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(YMD_FORMAT_STRING); String sql = null; @@ -198,7 +198,7 @@ public static KeyValue savePublicationRep(Connection con,PublicationRep publicat } public static int deletePublicationRep(Connection con, KeyValue pubID, User user, DatabaseSyntax databaseSyntax) throws SQLException, DataAccessException{ - checkRolePermission(con, user, User.SPECIAL_CLAIM.publicationEditors, "edit publications", databaseSyntax); + checkRolePermission(con, user, SpecialUser.SPECIAL_CLAIM.publicationEditors, "edit publications", databaseSyntax); String sql = "DELETE FROM "+PublicationTable.table.getTableName()+" WHERE ID='"+pubID+"'"; if (lg.isDebugEnabled()) lg.debug(sql); @@ -512,7 +512,7 @@ public static VCDocumentInfo curate(CurateSpec curateSpec, Connection con, User updatedVersionFlag = VersionFlag.Archived; } else if(curateSpec.getCurateType() == CurateSpec.PUBLISH){ //Must have PUBLISH rights - if (!(user instanceof User.SpecialUser specialUser) || !specialUser.isPublisher()) { + if (!(user instanceof SpecialUser specialUser) || !specialUser.isPublisher()) { throw new PermissionException("Cannot curate " + vType.getTypeName() + " \"" + dbVersion.getName() + "\" (" + vKey + "), user " + user.getName() + " not granted PUBLISHING rights"); } //Must be ARCHIVED and Public before PUBLISH is allowed @@ -1221,8 +1221,8 @@ private static User getUserFromUserid(Connection con, String userid) throws SQLE return user; } - public static TreeMap> getSpecialUsers(User user, Connection con, DatabaseSyntax dbSyntax) throws DataAccessException, java.sql.SQLException{ - TreeMap> result = new TreeMap<>(); + public static TreeMap> getSpecialUsers(User user, Connection con, DatabaseSyntax dbSyntax) throws DataAccessException, java.sql.SQLException{ + TreeMap> result = new TreeMap<>(); String sql = "SELECT " + SpecialUsersTable.table.userRef.getQualifiedColName() + " userref," + SpecialUsersTable.table.special.getQualifiedColName() + " special," + @@ -1234,7 +1234,7 @@ public static TreeMap> getSpecialUsers try (ResultSet rset = stmt.executeQuery(sql);) { while (rset.next()) { String specialStr = rset.getString("special"); - User.SPECIAL_CLAIM special = User.SPECIAL_CLAIM.fromDatabase(specialStr); + SpecialUser.SPECIAL_CLAIM special = SpecialUser.SPECIAL_CLAIM.fromDatabase(specialStr); String userdetail = rset.getString("userdetail"); String userRef = rset.getString("userref"); String userId = rset.getString("userid"); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/LocalAdminDbServer.java b/vcell-server/src/main/java/cbit/vcell/modeldb/LocalAdminDbServer.java index 2a69ea61bb..cbd7a6960b 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/LocalAdminDbServer.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/LocalAdminDbServer.java @@ -17,11 +17,7 @@ import org.vcell.db.KeyFactory; import org.vcell.util.DataAccessException; import org.vcell.util.UseridIDExistsException; -import org.vcell.util.document.ExternalDataIdentifier; -import org.vcell.util.document.KeyValue; -import org.vcell.util.document.User; -import org.vcell.util.document.UserInfo; -import org.vcell.util.document.UserLoginInfo; +import org.vcell.util.document.*; import cbit.vcell.server.AdminDatabaseServer; import cbit.vcell.server.SimpleJobStatusPersistent; @@ -120,7 +116,7 @@ public SimulationJobStatusPersistent[] getSimulationJobStatus(boolean bActiveOnl /** * getUser method comment. */ -public User.SpecialUser getUser(String userid) throws DataAccessException { +public SpecialUser getUser(String userid) throws DataAccessException { try { return adminDbTop.getUser(userid,true); }catch (Throwable e){ diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/LocalUserMetaDbServer.java b/vcell-server/src/main/java/cbit/vcell/modeldb/LocalUserMetaDbServer.java index 057499af3b..4499a24be8 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/LocalUserMetaDbServer.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/LocalUserMetaDbServer.java @@ -51,7 +51,7 @@ public LocalUserMetaDbServer(ConnectionFactory conFactory, KeyFactory keyFactory dbServerImpl = new DatabaseServerImpl(conFactory,keyFactory); } -public TreeMap> getSpecialUsers() throws DataAccessException{ +public TreeMap> getSpecialUsers() throws DataAccessException{ return dbServerImpl.getSpecialUsers(user); } /** diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java index 0a62c094a6..520221acb3 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java @@ -26,10 +26,7 @@ import org.vcell.util.BeanUtils; import org.vcell.util.DataAccessException; import org.vcell.util.ObjectNotFoundException; -import org.vcell.util.document.KeyValue; -import org.vcell.util.document.User; -import org.vcell.util.document.UserInfo; -import org.vcell.util.document.UserLoginInfo; +import org.vcell.util.document.*; import java.math.BigDecimal; import java.security.SecureRandom; @@ -54,7 +51,7 @@ public UserDbDriver() { } -public User.SpecialUser getUserFromUserid(Connection con, String userid) throws SQLException { +public SpecialUser getUserFromUserid(Connection con, String userid) throws SQLException { PreparedStatement pstmt; String sql; ResultSet rset; @@ -73,7 +70,7 @@ public User.SpecialUser getUserFromUserid(Connection con, String userid) throws pstmt = con.prepareStatement(sql); pstmt.setString(1, userid); BigDecimal userKey = null; - ArrayList specials = new ArrayList<>(); + ArrayList specials = new ArrayList<>(); try { rset = pstmt.executeQuery(); while (rset.next()) { @@ -86,7 +83,7 @@ public User.SpecialUser getUserFromUserid(Connection con, String userid) throws String special = rset.getString("special"); if(!rset.wasNull()) { try { - specials.add(User.SPECIAL_CLAIM.fromDatabase(special)); + specials.add(SpecialUser.SPECIAL_CLAIM.fromDatabase(special)); }catch(Exception e) { //keep going lg.error(e.getMessage(), e); @@ -99,7 +96,7 @@ public User.SpecialUser getUserFromUserid(Connection con, String userid) throws if(userKey == null) { return null; } - return new User.SpecialUser(userid, new KeyValue(userKey),specials.toArray(new User.SPECIAL_CLAIM[0])); + return new SpecialUser(userid, new KeyValue(userKey),specials.toArray(new SpecialUser.SPECIAL_CLAIM[0])); } public boolean removeUserIdentity(Connection con, User user, String authSubject, String authIssuer) throws SQLException { @@ -171,12 +168,12 @@ public List getUserIdentitiesFromSubjectAndIssuer(Connection con, int lastUserAdded = userIdentities.size()-1; boolean sameUser = !userIdentities.isEmpty() && userIdentities.get(lastUserAdded).getId().equals(userKey); if (sameUser && claim != null){ - userIdentities.get(lastUserAdded).getUserBuilder().addSpecial(User.SPECIAL_CLAIM.fromDatabase(claim)); + userIdentities.get(lastUserAdded).getUserBuilder().addSpecial(SpecialUser.SPECIAL_CLAIM.fromDatabase(claim)); } else{ String userID = rset.getString(UserTable.table.userid.getUnqualifiedColName()); - User.SpecialUserBuilder builder = new User.SpecialUserBuilder(userID, new KeyValue(userKey)); + SpecialUser.SpecialUserBuilder builder = new SpecialUser.SpecialUserBuilder(userID, new KeyValue(userKey)); if (claim != null){ - builder.addSpecial(User.SPECIAL_CLAIM.fromDatabase(claim)); + builder.addSpecial(SpecialUser.SPECIAL_CLAIM.fromDatabase(claim)); } userIdentities.add(new UserIdentityBuilder(userKey, builder, subject, issuer, UserIdentityTable.table.getUserIdentityDate(rset))); diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityBuilder.java b/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityBuilder.java index 3296c9691a..8a06142a83 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityBuilder.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/UserIdentityBuilder.java @@ -1,5 +1,6 @@ package cbit.vcell.modeldb; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import java.math.BigDecimal; @@ -10,9 +11,9 @@ public class UserIdentityBuilder { private final String subject; private final String issuer; private final LocalDateTime insertDate; - private final User.SpecialUserBuilder userBuilder; + private final SpecialUser.SpecialUserBuilder userBuilder; - public UserIdentityBuilder(BigDecimal id, User.SpecialUserBuilder specialUserBuilder, + public UserIdentityBuilder(BigDecimal id, SpecialUser.SpecialUserBuilder specialUserBuilder, String subject, String issuer, LocalDateTime insertDate){ this.id = id; this.subject = subject; @@ -25,7 +26,7 @@ public BigDecimal getId(){ return id; } - public User.SpecialUserBuilder getUserBuilder(){ + public SpecialUser.SpecialUserBuilder getUserBuilder(){ return userBuilder; } diff --git a/vcell-server/src/main/java/org/vcell/auth/JWTUtils.java b/vcell-server/src/main/java/org/vcell/auth/JWTUtils.java index 72b4fa24be..6b3e103765 100644 --- a/vcell-server/src/main/java/org/vcell/auth/JWTUtils.java +++ b/vcell-server/src/main/java/org/vcell/auth/JWTUtils.java @@ -17,6 +17,7 @@ import org.jose4j.jwt.consumer.JwtConsumerBuilder; import org.jose4j.lang.JoseException; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import java.io.IOException; @@ -206,8 +207,8 @@ public static String createLegacyAccessToken(User user, NumericDate expirationTi claims.setIssuedAtToNow(); // when the token was issued/created (now) claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago) claims.setSubject(user.toSubject()); // the subject/principal is whom the token is about - if (user instanceof User.SpecialUser){ - User.SPECIAL_CLAIM[] specialClaims = ((User.SpecialUser)user).getMySpecials(); + if (user instanceof SpecialUser){ + SpecialUser.SPECIAL_CLAIM[] specialClaims = ((SpecialUser)user).getMySpecials(); if (specialClaims != null && specialClaims.length>0){ List groups = Arrays.stream(specialClaims).map(specialClaim -> specialClaim.name()).collect(Collectors.toList()); claims.setStringListClaim("groups", groups); // multi-valued claims will end up as a JSON array diff --git a/vcell-server/src/test/java/cbit/vcell/message/server/dispatcher/MockSimulationDB.java b/vcell-server/src/test/java/cbit/vcell/message/server/dispatcher/MockSimulationDB.java index 30fe536545..f67194dc46 100644 --- a/vcell-server/src/test/java/cbit/vcell/message/server/dispatcher/MockSimulationDB.java +++ b/vcell-server/src/test/java/cbit/vcell/message/server/dispatcher/MockSimulationDB.java @@ -18,8 +18,8 @@ public class MockSimulationDB implements SimulationDatabase{ private HashMap> dbTable = new HashMap<>(); - public static User.SpecialUser specialAdmin = new User.SpecialUser("Tom", new KeyValue("999"), new User.SPECIAL_CLAIM[User.SPECIAL_CLAIM.admins.ordinal()]); - public static User.SpecialUser powerUser = new User.SpecialUser("Tim", new KeyValue("2"), new User.SPECIAL_CLAIM[]{User.SpecialUser.SPECIAL_CLAIM.powerUsers}); + public static SpecialUser specialAdmin = new SpecialUser("Tom", new KeyValue("999"), new SpecialUser.SPECIAL_CLAIM[SpecialUser.SPECIAL_CLAIM.admins.ordinal()]); + public static SpecialUser powerUser = new SpecialUser("Tim", new KeyValue("2"), new SpecialUser.SPECIAL_CLAIM[]{SpecialUser.SPECIAL_CLAIM.powerUsers}); private final HashMap users = new HashMap<>(){ {put(specialAdmin.getName(), specialAdmin); put(DispatcherTestUtils.alice.getName(), DispatcherTestUtils.alice); @@ -149,21 +149,21 @@ public Set getUnreferencedSimulations() throws SQLException { } @Override - public User.SpecialUser getUser(String username) throws DataAccessException, SQLException { + public SpecialUser getUser(String username) throws DataAccessException, SQLException { User user = users.get(username); - if (user instanceof User.SpecialUser){ - return (User.SpecialUser) user; + if (user instanceof SpecialUser){ + return (SpecialUser) user; } - User.SpecialUser specialUser = new User.SpecialUser(user.getName(), user.getID(), new User.SPECIAL_CLAIM[]{}); + SpecialUser specialUser = new SpecialUser(user.getName(), user.getID(), new SpecialUser.SPECIAL_CLAIM[]{}); return specialUser; } @Override - public TreeMap> getSpecialUsers() throws DataAccessException, SQLException { - TreeMap> map = new TreeMap<>(); + public TreeMap> getSpecialUsers() throws DataAccessException, SQLException { + TreeMap> map = new TreeMap<>(); TreeMap subMap = new TreeMap<>(new User.UserNameComparator()); subMap.put(specialAdmin, "f"); - map.put(User.SPECIAL_CLAIM.admins, subMap); + map.put(SpecialUser.SPECIAL_CLAIM.admins, subMap); return map; } diff --git a/vcell-server/src/test/java/org/vcell/auth/JWTUtilsTest.java b/vcell-server/src/test/java/org/vcell/auth/JWTUtilsTest.java index af7aea66ff..91d2c82f5c 100644 --- a/vcell-server/src/test/java/org/vcell/auth/JWTUtilsTest.java +++ b/vcell-server/src/test/java/org/vcell/auth/JWTUtilsTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import java.io.IOException; @@ -97,7 +98,7 @@ public void testJWT() throws JoseException, MalformedClaimException { RsaJsonWebKey rsaJsonWebKey = JWTUtils.createNewJsonWebKey("k1"); JWTUtils.setRsaJsonWebKey(rsaJsonWebKey); - User user = new User.SpecialUser("testuser", new KeyValue("12345"), new User.SPECIAL_CLAIM[0]); + User user = new SpecialUser("testuser", new KeyValue("12345"), new SpecialUser.SPECIAL_CLAIM[0]); NumericDate expirationDate = NumericDate.now(); @@ -122,7 +123,7 @@ public void testJWT() throws JoseException, MalformedClaimException { public void testJWTWithStoredKeys() throws JoseException, MalformedClaimException { // test with keys stored in files JWTUtils.setRsaJsonWebKey(null); - User user = new User.SpecialUser("testuser", new KeyValue("12345"), new User.SPECIAL_CLAIM[0]); + User user = new SpecialUser("testuser", new KeyValue("12345"), new SpecialUser.SPECIAL_CLAIM[0]); NumericDate expirationDate = NumericDate.now(); expirationDate.addSeconds(1); From 0e61855fa7265de1dc6db1ebaa4e15193f97df92 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 16 Jun 2025 12:35:53 -0400 Subject: [PATCH 05/13] Generate Special User DTO --- python-restclient/.openapi-generator/FILES | 4 + python-restclient/README.md | 2 + python-restclient/docs/SPECIALCLAIM.md | 10 + python-restclient/docs/SpecialUser.md | 29 +++ python-restclient/docs/User.md | 1 + python-restclient/test/test_special_user.py | 60 +++++ python-restclient/test/test_specialclaim.py | 35 +++ python-restclient/vcell_client/__init__.py | 2 + .../vcell_client/models/__init__.py | 2 + .../vcell_client/models/special_user.py | 99 ++++++++ .../vcell_client/models/specialclaim.py | 48 ++++ python-restclient/vcell_client/models/user.py | 56 +++-- tools/generate.sh | 16 +- tools/openapi.yaml | 31 +++ .../org/vcell/util/document/SpecialUser.java | 11 + .../java/org/vcell/util/document/User.java | 13 + vcell-restclient/.openapi-generator/FILES | 4 + vcell-restclient/README.md | 2 + vcell-restclient/api/openapi.yaml | 48 ++++ vcell-restclient/docs/SPECIALCLAIM.md | 17 ++ vcell-restclient/docs/SpecialUser.md | 14 ++ vcell-restclient/docs/User.md | 1 + .../vcell/restclient/model/SPECIALCLAIM.java | 82 ++++++ .../vcell/restclient/model/SpecialUser.java | 233 ++++++++++++++++++ .../java/org/vcell/restclient/model/User.java | 62 ++++- .../restclient/utils/DtoModelTransforms.java | 8 + .../restclient/model/SPECIALCLAIMTest.java | 32 +++ .../restclient/model/SpecialUserTest.java | 91 +++++++ .../modules/openapi/.openapi-generator/FILES | 2 + .../app/core/modules/openapi/model/models.ts | 2 + .../modules/openapi/model/special-user.ts | 20 ++ .../modules/openapi/model/specialclaim.ts | 22 ++ .../app/core/modules/openapi/model/user.ts | 1 + 33 files changed, 1029 insertions(+), 31 deletions(-) create mode 100644 python-restclient/docs/SPECIALCLAIM.md create mode 100644 python-restclient/docs/SpecialUser.md create mode 100644 python-restclient/test/test_special_user.py create mode 100644 python-restclient/test/test_specialclaim.py create mode 100644 python-restclient/vcell_client/models/special_user.py create mode 100644 python-restclient/vcell_client/models/specialclaim.py create mode 100644 vcell-restclient/docs/SPECIALCLAIM.md create mode 100644 vcell-restclient/docs/SpecialUser.md create mode 100644 vcell-restclient/src/main/java/org/vcell/restclient/model/SPECIALCLAIM.java create mode 100644 vcell-restclient/src/main/java/org/vcell/restclient/model/SpecialUser.java create mode 100644 vcell-restclient/src/test/java/org/vcell/restclient/model/SPECIALCLAIMTest.java create mode 100644 vcell-restclient/src/test/java/org/vcell/restclient/model/SpecialUserTest.java create mode 100644 webapp-ng/src/app/core/modules/openapi/model/special-user.ts create mode 100644 webapp-ng/src/app/core/modules/openapi/model/specialclaim.ts diff --git a/python-restclient/.openapi-generator/FILES b/python-restclient/.openapi-generator/FILES index 28cc426bca..270f2c7cbd 100644 --- a/python-restclient/.openapi-generator/FILES +++ b/python-restclient/.openapi-generator/FILES @@ -41,6 +41,7 @@ docs/Origin.md docs/Publication.md docs/PublicationInfo.md docs/PublicationResourceApi.md +docs/SPECIALCLAIM.md docs/SchedulerStatus.md docs/SimulationExecutionStatusRecord.md docs/SimulationJobStatusRecord.md @@ -51,6 +52,7 @@ docs/SimulationResourceApi.md docs/SimulationStatusPersistentRecord.md docs/SolverResourceApi.md docs/SourceModel.md +docs/SpecialUser.md docs/Status.md docs/StatusMessage.md docs/User.md @@ -127,6 +129,8 @@ vcell_client/models/simulation_queue_entry_status_record.py vcell_client/models/simulation_queue_id.py vcell_client/models/simulation_status_persistent_record.py vcell_client/models/source_model.py +vcell_client/models/special_user.py +vcell_client/models/specialclaim.py vcell_client/models/status.py vcell_client/models/status_message.py vcell_client/models/user.py diff --git a/python-restclient/README.md b/python-restclient/README.md index f5dbe2f6ae..c4d28d7cb2 100644 --- a/python-restclient/README.md +++ b/python-restclient/README.md @@ -173,6 +173,7 @@ Class | Method | HTTP request | Description - [Origin](docs/Origin.md) - [Publication](docs/Publication.md) - [PublicationInfo](docs/PublicationInfo.md) + - [SPECIALCLAIM](docs/SPECIALCLAIM.md) - [SchedulerStatus](docs/SchedulerStatus.md) - [SimulationExecutionStatusRecord](docs/SimulationExecutionStatusRecord.md) - [SimulationJobStatusRecord](docs/SimulationJobStatusRecord.md) @@ -181,6 +182,7 @@ Class | Method | HTTP request | Description - [SimulationQueueID](docs/SimulationQueueID.md) - [SimulationStatusPersistentRecord](docs/SimulationStatusPersistentRecord.md) - [SourceModel](docs/SourceModel.md) + - [SpecialUser](docs/SpecialUser.md) - [Status](docs/Status.md) - [StatusMessage](docs/StatusMessage.md) - [User](docs/User.md) diff --git a/python-restclient/docs/SPECIALCLAIM.md b/python-restclient/docs/SPECIALCLAIM.md new file mode 100644 index 0000000000..0f3fe3e05e --- /dev/null +++ b/python-restclient/docs/SPECIALCLAIM.md @@ -0,0 +1,10 @@ +# SPECIALCLAIM + + +## 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/SpecialUser.md b/python-restclient/docs/SpecialUser.md new file mode 100644 index 0000000000..cd45a20049 --- /dev/null +++ b/python-restclient/docs/SpecialUser.md @@ -0,0 +1,29 @@ +# SpecialUser + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**is_special** | **str** | | [default to 'yes'] +**my_specials** | [**List[SPECIALCLAIM]**](SPECIALCLAIM.md) | | [optional] + +## Example + +```python +from vcell_client.models.special_user import SpecialUser + +# TODO update the JSON string below +json = "{}" +# create an instance of SpecialUser from a JSON string +special_user_instance = SpecialUser.from_json(json) +# print the JSON string representation of the object +print SpecialUser.to_json() + +# convert the object into a dict +special_user_dict = special_user_instance.to_dict() +# create an instance of SpecialUser from a dict +special_user_form_dict = special_user.from_dict(special_user_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/User.md b/python-restclient/docs/User.md index 4487ad9527..26e3715e1b 100644 --- a/python-restclient/docs/User.md +++ b/python-restclient/docs/User.md @@ -4,6 +4,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**is_special** | **str** | | [default to 'no'] **user_name** | **str** | | [optional] **key** | **str** | | [optional] diff --git a/python-restclient/test/test_special_user.py b/python-restclient/test/test_special_user.py new file mode 100644 index 0000000000..b4d8d98bfe --- /dev/null +++ b/python-restclient/test/test_special_user.py @@ -0,0 +1,60 @@ +# 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.special_user import SpecialUser + +class TestSpecialUser(unittest.TestCase): + """SpecialUser unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> SpecialUser: + """Test SpecialUser + 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 `SpecialUser` + """ + model = SpecialUser() + if include_optional: + return SpecialUser( + user_name = '', + key = '', + my_specials = [ + 'admins' + ], + admin = True, + publisher = True, + v_cell_support = True + ) + else: + return SpecialUser( + ) + """ + + def testSpecialUser(self): + """Test SpecialUser""" + # 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_specialclaim.py b/python-restclient/test/test_specialclaim.py new file mode 100644 index 0000000000..71467a6abf --- /dev/null +++ b/python-restclient/test/test_specialclaim.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.specialclaim import SPECIALCLAIM + +class TestSPECIALCLAIM(unittest.TestCase): + """SPECIALCLAIM unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testSPECIALCLAIM(self): + """Test SPECIALCLAIM""" + # inst = SPECIALCLAIM() + +if __name__ == '__main__': + unittest.main() diff --git a/python-restclient/vcell_client/__init__.py b/python-restclient/vcell_client/__init__.py index 76d5629802..13c39295c3 100644 --- a/python-restclient/vcell_client/__init__.py +++ b/python-restclient/vcell_client/__init__.py @@ -74,6 +74,7 @@ from vcell_client.models.origin import Origin from vcell_client.models.publication import Publication from vcell_client.models.publication_info import PublicationInfo +from vcell_client.models.specialclaim import SPECIALCLAIM from vcell_client.models.scheduler_status import SchedulerStatus from vcell_client.models.simulation_execution_status_record import SimulationExecutionStatusRecord from vcell_client.models.simulation_job_status_record import SimulationJobStatusRecord @@ -82,6 +83,7 @@ from vcell_client.models.simulation_queue_id import SimulationQueueID from vcell_client.models.simulation_status_persistent_record import SimulationStatusPersistentRecord from vcell_client.models.source_model import SourceModel +from vcell_client.models.special_user import SpecialUser from vcell_client.models.status import Status from vcell_client.models.status_message import StatusMessage from vcell_client.models.user import User diff --git a/python-restclient/vcell_client/models/__init__.py b/python-restclient/vcell_client/models/__init__.py index 587c3d9d34..f9b09c4f80 100644 --- a/python-restclient/vcell_client/models/__init__.py +++ b/python-restclient/vcell_client/models/__init__.py @@ -48,6 +48,7 @@ from vcell_client.models.origin import Origin from vcell_client.models.publication import Publication from vcell_client.models.publication_info import PublicationInfo +from vcell_client.models.specialclaim import SPECIALCLAIM from vcell_client.models.scheduler_status import SchedulerStatus from vcell_client.models.simulation_execution_status_record import SimulationExecutionStatusRecord from vcell_client.models.simulation_job_status_record import SimulationJobStatusRecord @@ -56,6 +57,7 @@ from vcell_client.models.simulation_queue_id import SimulationQueueID from vcell_client.models.simulation_status_persistent_record import SimulationStatusPersistentRecord from vcell_client.models.source_model import SourceModel +from vcell_client.models.special_user import SpecialUser from vcell_client.models.status import Status from vcell_client.models.status_message import StatusMessage from vcell_client.models.user import User diff --git a/python-restclient/vcell_client/models/special_user.py b/python-restclient/vcell_client/models/special_user.py new file mode 100644 index 0000000000..01caa1172a --- /dev/null +++ b/python-restclient/vcell_client/models/special_user.py @@ -0,0 +1,99 @@ +# 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 StrictStr +from pydantic import Field +from vcell_client.models.specialclaim import SPECIALCLAIM +from vcell_client.models.user import User +try: + from typing import Self +except ImportError: + from typing_extensions import Self + +class SpecialUser(User): + """ + SpecialUser + """ # noqa: E501 + is_special: StrictStr = Field(alias="isSpecial") + my_specials: Optional[List[SPECIALCLAIM]] = Field(default=None, alias="mySpecials") + __properties: ClassVar[List[str]] = ["isSpecial", "userName", "key"] + + 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 SpecialUser 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 SpecialUser 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 SpecialUser) in the input: " + _key) + + _obj = cls.model_validate({ + "isSpecial": obj.get("isSpecial") if obj.get("isSpecial") is not None else 'yes', + "userName": obj.get("userName"), + "key": obj.get("key") + }) + return _obj + + diff --git a/python-restclient/vcell_client/models/specialclaim.py b/python-restclient/vcell_client/models/specialclaim.py new file mode 100644 index 0000000000..8bab6a91c7 --- /dev/null +++ b/python-restclient/vcell_client/models/specialclaim.py @@ -0,0 +1,48 @@ +# 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 SPECIALCLAIM(str, Enum): + """ + SPECIALCLAIM + """ + + """ + allowed enum values + """ + ADMINS = 'admins' + POWERUSERS = 'powerUsers' + PUBLICATIONEDITORS = 'publicationEditors' + VCELLSUPPORT = 'vcellSupport' + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of SPECIALCLAIM from a JSON string""" + return cls(json.loads(json_str)) + + diff --git a/python-restclient/vcell_client/models/user.py b/python-restclient/vcell_client/models/user.py index 023b60b56f..726894bebf 100644 --- a/python-restclient/vcell_client/models/user.py +++ b/python-restclient/vcell_client/models/user.py @@ -19,7 +19,7 @@ import json -from typing import Any, ClassVar, Dict, List, Optional +from typing import Any, ClassVar, Dict, List, Optional, Union from pydantic import BaseModel, StrictStr from pydantic import Field try: @@ -31,9 +31,10 @@ class User(BaseModel): """ User """ # noqa: E501 + is_special: StrictStr = Field(alias="isSpecial") user_name: Optional[StrictStr] = Field(default=None, alias="userName") key: Optional[StrictStr] = None - __properties: ClassVar[List[str]] = ["userName", "key"] + __properties: ClassVar[List[str]] = ["isSpecial", "userName", "key"] model_config = { "populate_by_name": True, @@ -41,6 +42,23 @@ class User(BaseModel): } + # JSON field name that stores the object type + __discriminator_property_name: ClassVar[List[str]] = 'isSpecial' + + # discriminator mappings + __discriminator_value_class_map: ClassVar[Dict[str, str]] = { + 'no': 'User','yes': 'SpecialUser' + } + + @classmethod + def get_discriminator_value(cls, obj: Dict) -> str: + """Returns the discriminator value (object type) of the data""" + discriminator_value = obj[cls.__discriminator_property_name] + if discriminator_value: + return cls.__discriminator_value_class_map.get(discriminator_value) + else: + return None + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -51,7 +69,7 @@ def to_json(self) -> str: return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> Self: + def from_json(cls, json_str: str) -> Union[Self]: """Create an instance of User from a JSON string""" return cls.from_dict(json.loads(json_str)) @@ -74,23 +92,19 @@ def to_dict(self) -> Dict[str, Any]: return _dict @classmethod - def from_dict(cls, obj: Dict) -> Self: + def from_dict(cls, obj: Dict) -> Union[Self]: """Create an instance of User 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 User) in the input: " + _key) - - _obj = cls.model_validate({ - "userName": obj.get("userName"), - "key": obj.get("key") - }) - return _obj - + # look up the object type based on discriminator mapping + object_type = cls.get_discriminator_value(obj) + if object_type: + klass = globals()[object_type] + return klass.from_dict(obj) + else: + raise ValueError("User failed to lookup discriminator value from " + + json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name + + ", mapping: " + json.dumps(cls.__discriminator_value_class_map)) + +from vcell_client.models.special_user import SpecialUser +# TODO: Rewrite to not use raise_errors +User.model_rebuild(raise_errors=False) diff --git a/tools/generate.sh b/tools/generate.sh index a7b1b12763..8a2b8e4b3f 100755 --- a/tools/generate.sh +++ b/tools/generate.sh @@ -22,14 +22,14 @@ docker run --rm -v ${parentDir}:/vcell \ -o /vcell/vcell-restclient \ -c /vcell/tools/java-config.yaml -# Apply the patch to AdminResourceApi.java to treat getUsage() as a PDF file rather than a JSON file -pushd "${parentDir}" || { echo "Failed to change directory to ${parentDir}"; exit 1; } -if ! git apply "${scriptDir}/FieldDataResourceApi.patch"; then - echo "Failed to apply FieldDataResourceApi.patch" - exit 1 -fi -popd || { echo "Failed to return to the previous directory"; exit 1; } - +## Apply the patch to AdminResourceApi.java to treat getUsage() as a PDF file rather than a JSON file +#pushd "${parentDir}" || { echo "Failed to change directory to ${parentDir}"; exit 1; } +#if ! git apply "${scriptDir}/FieldDataResourceApi.patch"; then +# echo "Failed to apply FieldDataResourceApi.patch" +# exit 1 +#fi +#popd || { echo "Failed to return to the previous directory"; exit 1; } +# docker run --rm -v ${parentDir}:/vcell \ ${generatorCliImage} generate \ diff --git a/tools/openapi.yaml b/tools/openapi.yaml index 9544df2a22..7ae214ad78 100644 --- a/tools/openapi.yaml +++ b/tools/openapi.yaml @@ -2429,6 +2429,13 @@ components: theHashCode: format: int32 type: integer + SPECIAL_CLAIM: + enum: + - admins + - powerUsers + - publicationEditors + - vcellSupport + type: string SchedulerStatus: enum: - WAITING @@ -2522,6 +2529,20 @@ components: type: string modelType: $ref: '#/components/schemas/ModelType' + SpecialUser: + required: + - isSpecial + type: object + allOf: + - $ref: '#/components/schemas/User' + properties: + isSpecial: + default: "yes" + type: string + mySpecials: + type: array + items: + $ref: '#/components/schemas/SPECIAL_CLAIM' Status: enum: - UNKNOWN @@ -2551,12 +2572,22 @@ components: format: double type: number User: + required: + - isSpecial type: object properties: + isSpecial: + default: "no" + type: string userName: type: string key: $ref: '#/components/schemas/KeyValue' + discriminator: + propertyName: isSpecial + mapping: + "no": '#/components/schemas/User' + "yes": '#/components/schemas/SpecialUser' UserIdentityJSONSafe: type: object properties: diff --git a/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java b/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java index 9773c99e82..ec4250ffcc 100644 --- a/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java +++ b/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java @@ -1,5 +1,9 @@ package org.vcell.util.document; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.eclipse.microprofile.openapi.annotations.enums.SchemaType; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.media.SchemaProperty; import org.vcell.util.Immutable; import org.vcell.util.Matchable; @@ -7,11 +11,15 @@ import java.util.ArrayList; import java.util.Arrays; + +@Schema(allOf = {User.class}, requiredProperties = {"isSpecial"}, properties = {@SchemaProperty(name = "isSpecial", defaultValue = "yes", type = SchemaType.STRING)}) public class SpecialUser extends User implements Serializable, Matchable, Immutable { private final static String PREVIOUS_DATABASE_VALUE_ADMIN = "special0"; private final static String PREVIOUS_DATABASE_VALUE_POWERUSER = "special1"; private final static String PREVIOUS_DATABASE_VALUE_PUBLICATION = "publication"; + public final String isSpecial = "yes"; + public enum SPECIAL_CLAIM { admins/*special0*/, powerUsers/*special1*/, @@ -47,14 +55,17 @@ public SPECIAL_CLAIM[] getMySpecials() { return mySpecials; } + @JsonIgnore public boolean isAdmin() { return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.admins); } + @JsonIgnore public boolean isPublisher() { return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.publicationEditors); } + @JsonIgnore public boolean isVCellSupport() { return Arrays.asList(mySpecials).contains(SPECIAL_CLAIM.vcellSupport); } diff --git a/vcell-core/src/main/java/org/vcell/util/document/User.java b/vcell-core/src/main/java/org/vcell/util/document/User.java index f63a2c2790..e6a91abe49 100644 --- a/vcell-core/src/main/java/org/vcell/util/document/User.java +++ b/vcell-core/src/main/java/org/vcell/util/document/User.java @@ -15,7 +15,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import org.eclipse.microprofile.openapi.annotations.enums.SchemaType; +import org.eclipse.microprofile.openapi.annotations.media.DiscriminatorMapping; import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.media.SchemaProperty; import org.vcell.util.Immutable; import org.vcell.util.Matchable; @@ -23,12 +26,22 @@ * This type was created in VisualAge. */ @SuppressWarnings("serial") +@Schema( + discriminatorProperty = "isSpecial", + discriminatorMapping = { + @DiscriminatorMapping(value = "no", schema = User.class), + @DiscriminatorMapping(value = "yes", schema = SpecialUser.class) + }, + requiredProperties = {"isSpecial"}, + properties = {@SchemaProperty(name = "isSpecial", defaultValue = "no", type = SchemaType.STRING)} +) public class User implements java.io.Serializable, Matchable, Immutable { @JsonProperty private String userName = null; @JsonProperty private KeyValue key = null; + public final String isSpecial = "no"; public static final String VCellTestAccountName = "vcelltestaccount"; public static final User tempUser = new User("temp",new KeyValue("123")); diff --git a/vcell-restclient/.openapi-generator/FILES b/vcell-restclient/.openapi-generator/FILES index 3c42f35497..3e22961fd5 100644 --- a/vcell-restclient/.openapi-generator/FILES +++ b/vcell-restclient/.openapi-generator/FILES @@ -41,6 +41,7 @@ docs/Origin.md docs/Publication.md docs/PublicationInfo.md docs/PublicationResourceApi.md +docs/SPECIALCLAIM.md docs/SchedulerStatus.md docs/SimulationExecutionStatusRecord.md docs/SimulationJobStatusRecord.md @@ -51,6 +52,7 @@ docs/SimulationResourceApi.md docs/SimulationStatusPersistentRecord.md docs/SolverResourceApi.md docs/SourceModel.md +docs/SpecialUser.md docs/Status.md docs/StatusMessage.md docs/User.md @@ -121,6 +123,7 @@ src/main/java/org/vcell/restclient/model/ModelType.java src/main/java/org/vcell/restclient/model/Origin.java src/main/java/org/vcell/restclient/model/Publication.java src/main/java/org/vcell/restclient/model/PublicationInfo.java +src/main/java/org/vcell/restclient/model/SPECIALCLAIM.java src/main/java/org/vcell/restclient/model/SchedulerStatus.java src/main/java/org/vcell/restclient/model/SimulationExecutionStatusRecord.java src/main/java/org/vcell/restclient/model/SimulationJobStatusRecord.java @@ -129,6 +132,7 @@ src/main/java/org/vcell/restclient/model/SimulationQueueEntryStatusRecord.java src/main/java/org/vcell/restclient/model/SimulationQueueID.java src/main/java/org/vcell/restclient/model/SimulationStatusPersistentRecord.java src/main/java/org/vcell/restclient/model/SourceModel.java +src/main/java/org/vcell/restclient/model/SpecialUser.java src/main/java/org/vcell/restclient/model/Status.java src/main/java/org/vcell/restclient/model/StatusMessage.java src/main/java/org/vcell/restclient/model/User.java diff --git a/vcell-restclient/README.md b/vcell-restclient/README.md index 7b43f875e2..59c117b1a1 100644 --- a/vcell-restclient/README.md +++ b/vcell-restclient/README.md @@ -236,6 +236,7 @@ Class | Method | HTTP request | Description - [Origin](docs/Origin.md) - [Publication](docs/Publication.md) - [PublicationInfo](docs/PublicationInfo.md) + - [SPECIALCLAIM](docs/SPECIALCLAIM.md) - [SchedulerStatus](docs/SchedulerStatus.md) - [SimulationExecutionStatusRecord](docs/SimulationExecutionStatusRecord.md) - [SimulationJobStatusRecord](docs/SimulationJobStatusRecord.md) @@ -244,6 +245,7 @@ Class | Method | HTTP request | Description - [SimulationQueueID](docs/SimulationQueueID.md) - [SimulationStatusPersistentRecord](docs/SimulationStatusPersistentRecord.md) - [SourceModel](docs/SourceModel.md) + - [SpecialUser](docs/SpecialUser.md) - [Status](docs/Status.md) - [StatusMessage](docs/StatusMessage.md) - [User](docs/User.md) diff --git a/vcell-restclient/api/openapi.yaml b/vcell-restclient/api/openapi.yaml index 460f0c587b..9a143ef422 100644 --- a/vcell-restclient/api/openapi.yaml +++ b/vcell-restclient/api/openapi.yaml @@ -2137,6 +2137,7 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: + specialUser: specialUser userName: userName key: key url: url @@ -2153,6 +2154,7 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: + specialUser: specialUser userName: userName key: key url: url @@ -2165,6 +2167,7 @@ components: version: date: 2000-01-23T04:56:07.000+00:00 owner: + specialUser: specialUser userName: userName key: key branchID: 0.8008281904610115 @@ -2349,6 +2352,7 @@ components: ExternalDataIdentifier: example: owner: + specialUser: specialUser userName: userName key: key dataKey: dataKey @@ -2457,6 +2461,7 @@ components: annotation: annotation fieldDataID: owner: + specialUser: specialUser userName: userName key: key dataKey: dataKey @@ -2572,6 +2577,7 @@ components: version: date: 2000-01-23T04:56:07.000+00:00 owner: + specialUser: specialUser userName: userName key: key branchID: 0.8008281904610115 @@ -2801,6 +2807,7 @@ components: version: date: 2000-01-23T04:56:07.000+00:00 owner: + specialUser: specialUser userName: userName key: key branchID: 0.8008281904610115 @@ -2835,6 +2842,7 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: + specialUser: specialUser userName: userName key: key url: url @@ -2851,6 +2859,7 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: + specialUser: specialUser userName: userName key: key url: url @@ -3019,6 +3028,7 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: + specialUser: specialUser userName: userName key: key url: url @@ -3059,6 +3069,13 @@ components: format: int32 type: integer type: object + SPECIAL_CLAIM: + enum: + - admins + - powerUsers + - publicationEditors + - vcellSupport + type: string SchedulerStatus: enum: - WAITING @@ -3124,6 +3141,7 @@ components: jobNumber: 0 fieldVCSimID: owner: + specialUser: specialUser userName: userName key: key simulationKey: simulationKey @@ -3228,6 +3246,25 @@ components: modelType: $ref: '#/components/schemas/ModelType' type: object + SpecialUser: + properties: + userName: + type: string + key: + type: string + specialUser: + type: string + mySpecials: + items: + $ref: '#/components/schemas/SPECIAL_CLAIM' + type: array + admin: + type: boolean + publisher: + type: boolean + vCellSupport: + type: boolean + type: object Status: enum: - UNKNOWN @@ -3268,6 +3305,7 @@ components: jobNumber: 0 fieldVCSimID: owner: + specialUser: specialUser userName: userName key: key simulationKey: simulationKey @@ -3296,7 +3334,13 @@ components: type: number type: object User: + discriminator: + mapping: + "no": '#/components/schemas/User' + "yes": '#/components/schemas/SpecialUser' + propertyName: specialUser example: + specialUser: specialUser userName: userName key: key properties: @@ -3304,6 +3348,8 @@ components: type: string key: type: string + specialUser: + type: string type: object UserIdentityJSONSafe: example: @@ -3363,6 +3409,7 @@ components: VCSimulationIdentifier: example: owner: + specialUser: specialUser userName: userName key: key simulationKey: simulationKey @@ -3471,6 +3518,7 @@ components: example: date: 2000-01-23T04:56:07.000+00:00 owner: + specialUser: specialUser userName: userName key: key branchID: 0.8008281904610115 diff --git a/vcell-restclient/docs/SPECIALCLAIM.md b/vcell-restclient/docs/SPECIALCLAIM.md new file mode 100644 index 0000000000..7815c915f4 --- /dev/null +++ b/vcell-restclient/docs/SPECIALCLAIM.md @@ -0,0 +1,17 @@ + + +# SPECIALCLAIM + +## Enum + + +* `ADMINS` (value: `"admins"`) + +* `POWERUSERS` (value: `"powerUsers"`) + +* `PUBLICATIONEDITORS` (value: `"publicationEditors"`) + +* `VCELLSUPPORT` (value: `"vcellSupport"`) + + + diff --git a/vcell-restclient/docs/SpecialUser.md b/vcell-restclient/docs/SpecialUser.md new file mode 100644 index 0000000000..049e3c0967 --- /dev/null +++ b/vcell-restclient/docs/SpecialUser.md @@ -0,0 +1,14 @@ + + +# SpecialUser + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**isSpecial** | **String** | | | +|**mySpecials** | **List<SPECIALCLAIM>** | | [optional] | + + + diff --git a/vcell-restclient/docs/User.md b/vcell-restclient/docs/User.md index 6eb4012db6..f955812d0e 100644 --- a/vcell-restclient/docs/User.md +++ b/vcell-restclient/docs/User.md @@ -7,6 +7,7 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| +|**isSpecial** | **String** | | | |**userName** | **String** | | [optional] | |**key** | **String** | | [optional] | diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/SPECIALCLAIM.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/SPECIALCLAIM.java new file mode 100644 index 0000000000..107cdf8236 --- /dev/null +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/SPECIALCLAIM.java @@ -0,0 +1,82 @@ +/* + * 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 SPECIAL_CLAIM + */ +public enum SPECIALCLAIM { + + ADMINS("admins"), + + POWERUSERS("powerUsers"), + + PUBLICATIONEDITORS("publicationEditors"), + + VCELLSUPPORT("vcellSupport"); + + private String value; + + SPECIALCLAIM(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static SPECIALCLAIM fromValue(String value) { + for (SPECIALCLAIM b : SPECIALCLAIM.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/SpecialUser.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/SpecialUser.java new file mode 100644 index 0000000000..9f228c9464 --- /dev/null +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/SpecialUser.java @@ -0,0 +1,233 @@ +/* + * 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.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +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.SPECIALCLAIM; +import org.vcell.restclient.model.User; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import org.vcell.restclient.JSON; +/** + * SpecialUser + */ +@JsonPropertyOrder({ + SpecialUser.JSON_PROPERTY_IS_SPECIAL, + SpecialUser.JSON_PROPERTY_MY_SPECIALS +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +@JsonIgnoreProperties( + value = "isSpecial", // ignore manually set isSpecial, it will be automatically generated by Jackson during serialization + allowSetters = true // allows the isSpecial to be set during deserialization +) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "isSpecial", visible = true) + +public class SpecialUser extends User { + public static final String JSON_PROPERTY_IS_SPECIAL = "isSpecial"; + private String isSpecial = "yes"; + + public static final String JSON_PROPERTY_MY_SPECIALS = "mySpecials"; + private List mySpecials; + + public SpecialUser() { + } + + public SpecialUser isSpecial(String isSpecial) { + this.isSpecial = isSpecial; + return this; + } + + /** + * Get isSpecial + * @return isSpecial + **/ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_IS_SPECIAL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getIsSpecial() { + return isSpecial; + } + + + @JsonProperty(JSON_PROPERTY_IS_SPECIAL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setIsSpecial(String isSpecial) { + this.isSpecial = isSpecial; + } + + + public SpecialUser mySpecials(List mySpecials) { + this.mySpecials = mySpecials; + return this; + } + + public SpecialUser addMySpecialsItem(SPECIALCLAIM mySpecialsItem) { + if (this.mySpecials == null) { + this.mySpecials = new ArrayList<>(); + } + this.mySpecials.add(mySpecialsItem); + return this; + } + + /** + * Get mySpecials + * @return mySpecials + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_MY_SPECIALS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getMySpecials() { + return mySpecials; + } + + + @JsonProperty(JSON_PROPERTY_MY_SPECIALS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMySpecials(List mySpecials) { + this.mySpecials = mySpecials; + } + + + @Override + public SpecialUser userName(String userName) { + this.setUserName(userName); + return this; + } + + @Override + public SpecialUser key(String key) { + this.setKey(key); + return this; + } + + /** + * Return true if this SpecialUser object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SpecialUser specialUser = (SpecialUser) o; + return Objects.equals(this.isSpecial, specialUser.isSpecial) && + Objects.equals(this.mySpecials, specialUser.mySpecials) && + super.equals(o); + } + + @Override + public int hashCode() { + return Objects.hash(isSpecial, mySpecials, super.hashCode()); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SpecialUser {\n"); + sb.append(" ").append(toIndentedString(super.toString())).append("\n"); + sb.append(" isSpecial: ").append(toIndentedString(isSpecial)).append("\n"); + sb.append(" mySpecials: ").append(toIndentedString(mySpecials)).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 `isSpecial` to the URL query string + if (getIsSpecial() != null) { + joiner.add(String.format("%sisSpecial%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getIsSpecial()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `userName` to the URL query string + if (getUserName() != null) { + joiner.add(String.format("%suserName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getUserName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + // add `key` to the URL query string + if (getKey() != null) { + joiner.add(String.format("%skey%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getKey()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + + return joiner.toString(); + } +static { + // Initialize and register the discriminator mappings. + Map> mappings = new HashMap>(); + mappings.put("SpecialUser", SpecialUser.class); + JSON.registerDiscriminator(SpecialUser.class, "isSpecial", mappings); +} +} + diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/User.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/User.java index 6ea3d168ec..43912351c9 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/User.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/User.java @@ -19,24 +19,42 @@ import java.util.Objects; import java.util.Map; import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonValue; import java.util.Arrays; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.vcell.restclient.JSON; /** * User */ @JsonPropertyOrder({ + User.JSON_PROPERTY_IS_SPECIAL, User.JSON_PROPERTY_USER_NAME, User.JSON_PROPERTY_KEY }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +@JsonIgnoreProperties( + value = "isSpecial", // ignore manually set isSpecial, it will be automatically generated by Jackson during serialization + allowSetters = true // allows the isSpecial to be set during deserialization +) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "isSpecial", visible = true) +@JsonSubTypes({ + @JsonSubTypes.Type(value = User.class, name = "no"), + @JsonSubTypes.Type(value = SpecialUser.class, name = "yes"), +}) + public class User { + public static final String JSON_PROPERTY_IS_SPECIAL = "isSpecial"; + private String isSpecial = "no"; + public static final String JSON_PROPERTY_USER_NAME = "userName"; private String userName; @@ -46,6 +64,31 @@ public class User { public User() { } + public User isSpecial(String isSpecial) { + this.isSpecial = isSpecial; + return this; + } + + /** + * Get isSpecial + * @return isSpecial + **/ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_IS_SPECIAL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getIsSpecial() { + return isSpecial; + } + + + @JsonProperty(JSON_PROPERTY_IS_SPECIAL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setIsSpecial(String isSpecial) { + this.isSpecial = isSpecial; + } + + public User userName(String userName) { this.userName = userName; return this; @@ -108,19 +151,21 @@ public boolean equals(Object o) { return false; } User user = (User) o; - return Objects.equals(this.userName, user.userName) && + return Objects.equals(this.isSpecial, user.isSpecial) && + Objects.equals(this.userName, user.userName) && Objects.equals(this.key, user.key); } @Override public int hashCode() { - return Objects.hash(userName, key); + return Objects.hash(isSpecial, userName, key); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class User {\n"); + sb.append(" isSpecial: ").append(toIndentedString(isSpecial)).append("\n"); sb.append(" userName: ").append(toIndentedString(userName)).append("\n"); sb.append(" key: ").append(toIndentedString(key)).append("\n"); sb.append("}"); @@ -170,6 +215,11 @@ public String toUrlQueryString(String prefix) { StringJoiner joiner = new StringJoiner("&"); + // add `isSpecial` to the URL query string + if (getIsSpecial() != null) { + joiner.add(String.format("%sisSpecial%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getIsSpecial()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + // add `userName` to the URL query string if (getUserName() != null) { joiner.add(String.format("%suserName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getUserName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); @@ -182,5 +232,13 @@ public String toUrlQueryString(String prefix) { return joiner.toString(); } +static { + // Initialize and register the discriminator mappings. + Map> mappings = new HashMap>(); + mappings.put("no", User.class); + mappings.put("yes", SpecialUser.class); + mappings.put("User", User.class); + JSON.registerDiscriminator(User.class, "isSpecial", mappings); +} } diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/utils/DtoModelTransforms.java b/vcell-restclient/src/main/java/org/vcell/restclient/utils/DtoModelTransforms.java index cc15b0daf1..b88025e4cc 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/utils/DtoModelTransforms.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/utils/DtoModelTransforms.java @@ -8,6 +8,7 @@ import cbit.vcell.math.VariableType; import cbit.vcell.simdata.DataIdentifier; import org.vcell.restclient.model.*; +import org.vcell.restclient.model.SpecialUser; import org.vcell.util.Extent; import org.vcell.util.Origin; import org.vcell.util.document.*; @@ -113,6 +114,13 @@ public static org.vcell.restclient.model.User userToDTO(User user) { } public static User dtoToUser(org.vcell.restclient.model.User dto){ + if (dto instanceof SpecialUser sp && sp.getMySpecials() != null) { + org.vcell.util.document.SpecialUser.SpecialUserBuilder builder = new org.vcell.util.document.SpecialUser.SpecialUserBuilder(dto.getUserName(), new KeyValue(dto.getKey())); + for (SPECIALCLAIM claim : sp.getMySpecials()){ + builder.addSpecial(org.vcell.util.document.SpecialUser.SPECIAL_CLAIM.valueOf(claim.getValue())); + } + return builder.build(); + } return new User(dto.getUserName(), new KeyValue(dto.getKey())); } diff --git a/vcell-restclient/src/test/java/org/vcell/restclient/model/SPECIALCLAIMTest.java b/vcell-restclient/src/test/java/org/vcell/restclient/model/SPECIALCLAIMTest.java new file mode 100644 index 0000000000..fbd0e08100 --- /dev/null +++ b/vcell-restclient/src/test/java/org/vcell/restclient/model/SPECIALCLAIMTest.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 SPECIALCLAIM + */ +public class SPECIALCLAIMTest { + /** + * Model tests for SPECIALCLAIM + */ + @Test + public void testSPECIALCLAIM() { + // TODO: test SPECIALCLAIM + } + +} diff --git a/vcell-restclient/src/test/java/org/vcell/restclient/model/SpecialUserTest.java b/vcell-restclient/src/test/java/org/vcell/restclient/model/SpecialUserTest.java new file mode 100644 index 0000000000..1ff3cf16a4 --- /dev/null +++ b/vcell-restclient/src/test/java/org/vcell/restclient/model/SpecialUserTest.java @@ -0,0 +1,91 @@ +/* + * 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.SPECIALCLAIM; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Model tests for SpecialUser + */ +public class SpecialUserTest { + private final SpecialUser model = new SpecialUser(); + + /** + * Model tests for SpecialUser + */ + @Test + public void testSpecialUser() { + // TODO: test SpecialUser + } + + /** + * Test the property 'userName' + */ + @Test + public void userNameTest() { + // TODO: test userName + } + + /** + * Test the property 'key' + */ + @Test + public void keyTest() { + // TODO: test key + } + + /** + * Test the property 'mySpecials' + */ + @Test + public void mySpecialsTest() { + // TODO: test mySpecials + } + + /** + * Test the property 'admin' + */ + @Test + public void adminTest() { + // TODO: test admin + } + + /** + * Test the property 'publisher' + */ + @Test + public void publisherTest() { + // TODO: test publisher + } + + /** + * Test the property 'vCellSupport' + */ + @Test + public void vCellSupportTest() { + // TODO: test vCellSupport + } + +} 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 e44ba01d2f..65345d9daf 100644 --- a/webapp-ng/src/app/core/modules/openapi/.openapi-generator/FILES +++ b/webapp-ng/src/app/core/modules/openapi/.openapi-generator/FILES @@ -68,6 +68,8 @@ model/simulation-queue-entry-status-record.ts model/simulation-queue-id.ts model/simulation-status-persistent-record.ts model/source-model.ts +model/special-user.ts +model/specialclaim.ts model/status-message.ts model/status.ts model/user-identity-json-safe.ts 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 bc3068738a..55adac9310 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/models.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/models.ts @@ -31,6 +31,7 @@ export * from './model-type'; export * from './origin'; export * from './publication'; export * from './publication-info'; +export * from './specialclaim'; export * from './scheduler-status'; export * from './simulation-execution-status-record'; export * from './simulation-job-status-record'; @@ -39,6 +40,7 @@ export * from './simulation-queue-entry-status-record'; export * from './simulation-queue-id'; export * from './simulation-status-persistent-record'; export * from './source-model'; +export * from './special-user'; export * from './status'; export * from './status-message'; export * from './user'; diff --git a/webapp-ng/src/app/core/modules/openapi/model/special-user.ts b/webapp-ng/src/app/core/modules/openapi/model/special-user.ts new file mode 100644 index 0000000000..8c36be5dde --- /dev/null +++ b/webapp-ng/src/app/core/modules/openapi/model/special-user.ts @@ -0,0 +1,20 @@ +/** + * 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 { SPECIALCLAIM } from './specialclaim'; +import { User } from './user'; + + +export interface SpecialUser extends User { + isSpecial: string; + mySpecials?: Array; +} + diff --git a/webapp-ng/src/app/core/modules/openapi/model/specialclaim.ts b/webapp-ng/src/app/core/modules/openapi/model/specialclaim.ts new file mode 100644 index 0000000000..cfcbf99064 --- /dev/null +++ b/webapp-ng/src/app/core/modules/openapi/model/specialclaim.ts @@ -0,0 +1,22 @@ +/** + * 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 SPECIALCLAIM = 'admins' | 'powerUsers' | 'publicationEditors' | 'vcellSupport'; + +export const SPECIALCLAIM = { + Admins: 'admins' as SPECIALCLAIM, + PowerUsers: 'powerUsers' as SPECIALCLAIM, + PublicationEditors: 'publicationEditors' as SPECIALCLAIM, + VcellSupport: 'vcellSupport' as SPECIALCLAIM +}; + diff --git a/webapp-ng/src/app/core/modules/openapi/model/user.ts b/webapp-ng/src/app/core/modules/openapi/model/user.ts index a19412c3f2..5d712aa4ea 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/user.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/user.ts @@ -12,6 +12,7 @@ export interface User { + isSpecial: string; userName?: string; key?: string; } From 9c858695684efb5543c3399446f5512d4ad18206 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 16 Jun 2025 13:35:15 -0400 Subject: [PATCH 06/13] Check If In Support Group Clause --- .../main/java/cbit/vcell/modeldb/DatabasePolicySQL.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabasePolicySQL.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabasePolicySQL.java index 29bad0f8f0..53fbde36fe 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabasePolicySQL.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabasePolicySQL.java @@ -15,6 +15,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.vcell.db.DatabaseSyntax; +import org.vcell.util.document.SpecialUser; import org.vcell.util.document.User; import cbit.sql.Field; @@ -303,6 +304,10 @@ public static String enforceOwnershipUpdate(User user, VersionTable vTable, Stri static String getVTableDirectSelectClause(VersionTable vTable,User user) { + String vcellSupportClause = ""; + if (user instanceof SpecialUser specialUser && specialUser.isVCellSupport()){ + vcellSupportClause = " OR " + GroupTable.table.userRef.getQualifiedColName() + " = " + PropertyLoader.getRequiredProperty(PropertyLoader.vcellSupportId); + } String sql = " ( "+ vTable.privacy.getQualifiedColName() + " = " + GroupTable.table.groupid.getQualifiedColName() + " AND " + @@ -321,6 +326,9 @@ static String getVTableDirectSelectClause(VersionTable vTable,User user) { // this user is in the access control list for this object // GroupTable.table.userRef.getQualifiedColName() + " = " + user.getID() + + // + // + vcellSupportClause + " ) "+ " ) "; return sql; From e3198d406056b212a3128d917d1ab873a5fbf4c9 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 16 Jun 2025 13:35:31 -0400 Subject: [PATCH 07/13] ACL Tests --- .../src/main/resources/application.properties | 4 + .../src/main/resources/scripts/init.sql | 5 +- .../org/vcell/restq/TestEndpointUtils.java | 10 +- .../org/vcell/restq/auth/ACLSupportTest.java | 129 ++++++++++++++++++ 4 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java diff --git a/vcell-rest/src/main/resources/application.properties b/vcell-rest/src/main/resources/application.properties index 5b17dd9228..206bb71cd8 100644 --- a/vcell-rest/src/main/resources/application.properties +++ b/vcell-rest/src/main/resources/application.properties @@ -67,6 +67,10 @@ quarkus.datasource.postgresql.db-kind=postgresql # %test.quarkus.datasource.postgresql.devservices.init-script-path=scripts/init.sql %test.quarkus.datasource.postgresql.jdbc.acquisition-timeout=120S +%test.quarkus.datasource.postgresql.devservices.port=32000 +%test.quarkus.datasource.postgresql.devservices.password=postgres +%test.quarkus.datasource.postgresql.devservices.username=postgres +%test.quarkus.datasource.postgresql.devservices.db-name=postgres %test.quarkus.keycloak.devservices.users.alice=alice %test.quarkus.keycloak.devservices.roles.alice=user,curator,owner,admin diff --git a/vcell-rest/src/main/resources/scripts/init.sql b/vcell-rest/src/main/resources/scripts/init.sql index 7b99bfa4ec..f338f9d49a 100644 --- a/vcell-rest/src/main/resources/scripts/init.sql +++ b/vcell-rest/src/main/resources/scripts/init.sql @@ -93,14 +93,17 @@ INSERT INTO vc_userinfo VALUES ( 2,'Administrator','1700596370260','Administrato INSERT INTO vc_userinfo VALUES ( 3,'vcellNagios','1700596370261','vcellNagios@example.com','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'A93453F7962799355608EC89D33D3249474E538F' ); INSERT INTO vc_userinfo VALUES ( 4,'VCellSupport','1714152297847','VCellSupport@example.com','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'C525EF5192F5DF966D0C891224EC5412FC6FD518' ); INSERT INTO vc_userinfo VALUES ( 140220477,'vcellguest','1700596370260','vcellguest@example.com','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'CD181552B879A2F29D10434D8ACF692B6C8126F9' ); +INSERT INTO vc_userinfo VALUES ( 5,'randomUser','1700596370260','user@example.com','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'CD181552B879A2F29D10434D8ACF692B6C8126F9' ); INSERT INTO vc_group VALUES (5,1,0,0,1); INSERT INTO vc_group VALUES (6,0,0,0,0); INSERT INTO vc_available VALUES (7,current_timestamp,'true',NULL,NULL); INSERT INTO vc_apiclient VALUES (8,'defaultApiClient','85133f8d-26f7-4247-8356-d175399fc2e6','98d000d6-adff-4f8f-a00e-6c28dbd8c571'); INSERT INTO vc_useridentity VALUES ( 9, 2,'auth0|65cb6311365d79c2fb96a005', 'https://dev-dzhx7i2db3x3kkvq.us.auth0.com/', CURRENT_TIMESTAMP); +INSERT INTO vc_useridentity VALUES ( 10, 5,'auth0|13432432432bv2344b962345', 'https://dev-dzhx7i2db3x3kkvq.us.auth0.com/', CURRENT_TIMESTAMP); INSERT INTO vc_specialusers VALUES ( 10,'publicationEditors',2,NULL); INSERT INTO vc_specialusers VALUES ( 11,'powerUsers',2,NULL); INSERT INTO vc_specialusers VALUES ( 12,'admins',2,NULL); +INSERT INTO vc_specialusers VALUES ( 13,'vcellSupport',2,NULL); INSERT INTO vc_userinfo VALUES ( 20,'dev0','1714152297847','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty','empty',CURRENT_TIMESTAMP,'C525EF5192F5DF966D0C891224EC5412FC6FD518' ); INSERT INTO vc_useridentity VALUES ( 21, 20,'google-oauth2|107511464785168320004', 'https://dev-dzhx7i2db3x3kkvq.us.auth0.com/', CURRENT_TIMESTAMP); @@ -108,5 +111,3 @@ INSERT INTO vc_specialusers VALUES ( 22,'publicationEditors',20,NULL); INSERT INTO vc_specialusers VALUES ( 23,'powerUsers',20,NULL); INSERT INTO vc_specialusers VALUES ( 24,'admins',20,NULL); INSERT INTO vc_publication VALUES ( 25,'Numerical Approach to Spatial Deterministic-Stochastic Models Arising in Cell Biology','Schaff, J.C., Gao, F., Li, Y., Novak, I.L., Slepchenko, B.M.',2016,'Schaff JC, Gao F, Li Y, Novak IL, Slepchenko BM. Numerical Approach to Spatial Deterministic-Stochastic Models Arising in Cell Biology. PLoS Comput Biol. 2016 Dec 13;12(12):e1005236. doi: 10.1371/journal.pcbi.1005236. PMID: 27959915; PMCID: PMC5154471.','27959915','10.1371/journal.pcbi.1005236',NULL,'http://www.vcell.org',NULL,CURRENT_TIMESTAMP ); -INSERT INTO vc_model VALUES ( 26,'ModelName',4,0,NULL,CURRENT_TIMESTAMP,0,NULL,27,NULL,NULL,NULL ); -INSERT INTO vc_biomodel VALUES ( 28,'BioModelName',4,0,NULL,CURRENT_TIMESTAMP,0,NULL,29,26,NULL,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 e75555a902..c7a6604936 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -43,10 +43,12 @@ public class TestEndpointUtils { - public static final String userAdminID = "2"; - public static final String userNagiosID = "3"; - public static final User vcellNagiosUser = new User("vcellNagios", new KeyValue(userNagiosID)); - public static final User administratorUser = new User("Administrator", new KeyValue(userAdminID)); + public static final String userAdminKey = "2"; + public static final String userNagiosKey = "3"; + public static final User vcellNagiosUser = new User("vcellNagios", new KeyValue(userNagiosKey)); + public static final User administratorUser = new User("Administrator", new KeyValue(userAdminKey)); + public static final User vcellSupportUser = new User("VCellSupport", new KeyValue("4")); + public static final User randomUser = new User("randomUser", new KeyValue("5")); public static final UserLoginInfoForMapping vcellNagiosUserLoginInfo = new UserLoginInfoForMapping().userID("vcellNagios").password("1700596370261"); public static final UserLoginInfoForMapping administratorUserLoginInfo = new UserLoginInfoForMapping().userID("Administrator").password("1700596370260"); diff --git a/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java b/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java new file mode 100644 index 0000000000..b0552535f7 --- /dev/null +++ b/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java @@ -0,0 +1,129 @@ +package org.vcell.restq.auth; + +import cbit.vcell.biomodel.BioModel; +import cbit.vcell.modeldb.AdminDBTopLevel; +import cbit.vcell.modeldb.DatabaseServerImpl; +import cbit.vcell.modeldb.UserIdentity; +import cbit.vcell.resource.PropertyLoader; +import cbit.vcell.server.UserRegistrationOP; +import cbit.vcell.xml.XMLSource; +import cbit.vcell.xml.XmlHelper; +import cbit.vcell.xml.XmlParseException; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.keycloak.client.KeycloakTestClient; +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; +import org.vcell.util.BigString; +import org.vcell.util.DataAccessException; +import org.vcell.util.document.BioModelInfo; +import org.vcell.util.document.SpecialUser; +import org.vcell.util.document.User; +import org.vcell.util.document.VersionableType; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +@QuarkusTest +public class ACLSupportTest { + @ConfigProperty(name = "quarkus.oidc.auth-server-url") + String authServerUrl; + + @ConfigProperty(name = "quarkus.http.test-port") + Integer testPort; + + @Inject + AgroalConnectionFactory agroalConnectionFactory; + + KeycloakTestClient keycloakClient = new KeycloakTestClient(); + + private final String randomUserOIDCSubject = "auth0|13432432432bv2344b962345"; + private final String randomUserOIDCIssuer = "https://dev-dzhx7i2db3x3kkvq.us.auth0.com/"; + private final String adminUserOIDCSubject = "auth0|65cb6311365d79c2fb96a005"; + private final String adminUserOIDCIssuer = "https://dev-dzhx7i2db3x3kkvq.us.auth0.com/"; + + private ApiClient aliceAPIClient; + private ApiClient bobAPIClient; + + @BeforeAll + public static void setupConfig(){ + PropertyLoader.setConfigProvider(new CDIVCellConfigProvider()); + } + + @BeforeEach + public void mapUsers() throws ApiException, DataAccessException, SQLException { + DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); + databaseServer.getAdminDBTopLevel().setUserIdentityFromIdentityProvider( + TestEndpointUtils.administratorUser, adminUserOIDCSubject, adminUserOIDCIssuer, true + ); + databaseServer.getAdminDBTopLevel().setUserIdentityFromIdentityProvider( + TestEndpointUtils.randomUser, randomUserOIDCSubject, randomUserOIDCIssuer, true + ); + } + + @AfterEach + public void unmapUsers() throws SQLException, DataAccessException { + TestEndpointUtils.removeAllMappings(agroalConnectionFactory); + } + + @Test + public void testOthersAccessToVCellSupport() throws IOException, DataAccessException, XmlParseException, SQLException { + DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); + User adminUser = databaseServer.getAdminDBTopLevel().getUserIdentitiesFromSubjectAndIssuer(adminUserOIDCSubject, adminUserOIDCIssuer, true).get(0).user(); + User randomUser = databaseServer.getAdminDBTopLevel().getUserIdentitiesFromSubjectAndIssuer(randomUserOIDCSubject, randomUserOIDCIssuer, true).get(0).user(); + + // Add BioModel owned by VCell Nagios, share it with VCell Support, ensure Admin has access and random user does not have access + String bioModelVCML = TestEndpointUtils.getResourceString("/TestVCML.vcml"); + BigString savedModelString = databaseServer.saveBioModel(TestEndpointUtils.vcellNagiosUser, new BigString(bioModelVCML), null); + BioModel savedModel = XmlHelper.XMLToBioModel(new XMLSource(savedModelString.toString())); + + databaseServer.groupAddUser(TestEndpointUtils.vcellNagiosUser, VersionableType.BioModelMetaData, savedModel.getVersion().getVersionKey(), + TestEndpointUtils.vcellSupportUser.getName(), true); + + BioModelInfo[] infos = databaseServer.getBioModelInfos(adminUser, true); + + // Only model admin has is the shared one, and the one saved by Nagios User + Assertions.assertEquals(1, infos.length); + Assertions.assertTrue(infos[0].getVersion().getVersionKey().compareEqual(savedModel.getVersion().getVersionKey())); + // Group access is only for VCell support + Assertions.assertTrue( infos[0].getVersion().getGroupAccess().isMember(TestEndpointUtils.vcellSupportUser)); + + // Should not have access to VCell support roles because random user does not have the support role + BioModelInfo[] randomUserInfos = databaseServer.getBioModelInfos(randomUser, true); + Assertions.assertEquals(0, randomUserInfos.length); + } + + @Test + public void testSpecialClaimsPeopleHave() throws SQLException, DataAccessException { + AdminDBTopLevel adminDBTopLevel = new AdminDBTopLevel(agroalConnectionFactory); + List randomUser = adminDBTopLevel.getUserIdentitiesFromSubjectAndIssuer(randomUserOIDCSubject, randomUserOIDCIssuer, true); + + // Random user has no special privileges + Assertions.assertEquals(1, randomUser.size()); + SpecialUser userIdentity = (SpecialUser) randomUser.get(0).user(); + Assertions.assertEquals("5", userIdentity.getID().toString()); + Assertions.assertEquals(0, userIdentity.getMySpecials().length); + + // Admin has all privileges + List adminIdentities = adminDBTopLevel.getUserIdentitiesFromSubjectAndIssuer(adminUserOIDCSubject, adminUserOIDCIssuer, true); + Assertions.assertEquals(1, adminIdentities.size()); + SpecialUser adminUser = (SpecialUser) adminIdentities.get(0).user(); + Assertions.assertEquals("2", adminUser.getID().toString()); + Assertions.assertEquals(4, adminUser.getMySpecials().length); + + Assertions.assertTrue(adminUser.isAdmin()); + Assertions.assertTrue(adminUser.isVCellSupport()); + Assertions.assertTrue(adminUser.isPublisher()); + } + + @Test + public void testVCellSupportIDGrabbing(){ + Assertions.assertEquals(PropertyLoader.getRequiredProperty(PropertyLoader.vcellSupportId), "4"); + } +} From 6aebe7b68806adf625555f43324fb5beb1249c14 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Mon, 16 Jun 2025 14:45:29 -0400 Subject: [PATCH 08/13] Get Identities From User is Private --- .../org/vcell/restq/TestEndpointUtils.java | 20 +++++------------- .../cbit/vcell/modeldb/AdminDBTopLevel.java | 21 ------------------- .../java/cbit/vcell/modeldb/UserDbDriver.java | 2 +- 3 files changed, 6 insertions(+), 37 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 c7a6604936..f19687ccd4 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -54,21 +54,11 @@ public class TestEndpointUtils { public static final UserLoginInfoForMapping administratorUserLoginInfo = new UserLoginInfoForMapping().userID("Administrator").password("1700596370260"); public static void removeAllMappings(AgroalConnectionFactory agroalConnectionFactory) throws DataAccessException, SQLException { - AdminDBTopLevel adminDBTopLevel = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()).getAdminDBTopLevel(); - adminDBTopLevel.getUserIdentitiesFromUser(TestEndpointUtils.vcellNagiosUser, true).stream().forEach(userIdentity -> { - try { - adminDBTopLevel.deleteUserIdentity(userIdentity.user(), userIdentity.subject(), userIdentity.issuer(), true); - } catch (SQLException | DataAccessException e) { - throw new RuntimeException(e); - } - }); - adminDBTopLevel.getUserIdentitiesFromUser(TestEndpointUtils.administratorUser, true).stream().forEach(userIdentity -> { - try { - adminDBTopLevel.deleteUserIdentity(userIdentity.user(), userIdentity.subject(), userIdentity.issuer(), true); - } catch (SQLException | DataAccessException e) { - throw new RuntimeException(e); - } - }); + Object object = new Object(); + Connection connection = agroalConnectionFactory.getConnection(object); + connection.prepareStatement("DELETE FROM VC_USERIDENTITY").execute(); + connection.commit(); + connection.close(); } public static void mapApiClientToAdmin(ApiClient apiClient) throws ApiException { diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java b/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java index b35dad648b..b6aae1e714 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/AdminDBTopLevel.java @@ -838,27 +838,6 @@ public List getUserIdentitiesFromSubjectAndIssuer(String subject, } } - public List getUserIdentitiesFromUser(User user, boolean bEnableRetry) - throws DataAccessException, java.sql.SQLException{ - - Object lock = new Object(); - Connection con = conFactory.getConnection(lock); - try { - return userDB.getUserIdentitiesFromUser(con, user); - } catch(Throwable e){ - lg.error("failure in getUserIdentitiesFromUser()", e); - if(bEnableRetry && isBadConnection(con)){ - conFactory.failed(con, lock); - return getUserIdentitiesFromUser(user, false); - } else { - handle_DataAccessException_SQLException(e); - return null; // never gets here; - } - } finally { - conFactory.release(con, lock); - } - } - public ApiAccessToken generateApiAccessToken(KeyValue apiClientKey, User user, Date expirationDate, boolean bEnableRetry) throws DataAccessException, java.sql.SQLException, ObjectNotFoundException{ diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java index 520221acb3..1d44717d29 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java @@ -221,7 +221,7 @@ public User getVCellSupportUser(Connection con) throws SQLException { } } - public List getUserIdentitiesFromUser(Connection con, User user) throws SQLException { + private List getUserIdentitiesFromUser(Connection con, User user) throws SQLException { Statement stmt; String sql; ResultSet rset; From 83a326b36f447d2456ac48fe1d549685bb958591 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Tue, 17 Jun 2025 07:46:54 -0400 Subject: [PATCH 09/13] Admin Does not Have Access to All BioModels --- .../java/org/vcell/restq/auth/ACLSupportTest.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java b/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java index b0552535f7..0c11c81ddb 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java @@ -5,7 +5,6 @@ import cbit.vcell.modeldb.DatabaseServerImpl; import cbit.vcell.modeldb.UserIdentity; import cbit.vcell.resource.PropertyLoader; -import cbit.vcell.server.UserRegistrationOP; import cbit.vcell.xml.XMLSource; import cbit.vcell.xml.XmlHelper; import cbit.vcell.xml.XmlParseException; @@ -72,8 +71,9 @@ public void unmapUsers() throws SQLException, DataAccessException { TestEndpointUtils.removeAllMappings(agroalConnectionFactory); } + // 1. Admin in VCellSupport group can access BioModel, 2. Random user can not access BioModel, 3. Admin can not access BioModel shared only with Random User @Test - public void testOthersAccessToVCellSupport() throws IOException, DataAccessException, XmlParseException, SQLException { + public void testBioModelAccess() throws IOException, DataAccessException, XmlParseException, SQLException { DatabaseServerImpl databaseServer = new DatabaseServerImpl(agroalConnectionFactory, agroalConnectionFactory.getKeyFactory()); User adminUser = databaseServer.getAdminDBTopLevel().getUserIdentitiesFromSubjectAndIssuer(adminUserOIDCSubject, adminUserOIDCIssuer, true).get(0).user(); User randomUser = databaseServer.getAdminDBTopLevel().getUserIdentitiesFromSubjectAndIssuer(randomUserOIDCSubject, randomUserOIDCIssuer, true).get(0).user(); @@ -91,12 +91,20 @@ public void testOthersAccessToVCellSupport() throws IOException, DataAccessExcep // Only model admin has is the shared one, and the one saved by Nagios User Assertions.assertEquals(1, infos.length); Assertions.assertTrue(infos[0].getVersion().getVersionKey().compareEqual(savedModel.getVersion().getVersionKey())); - // Group access is only for VCell support Assertions.assertTrue( infos[0].getVersion().getGroupAccess().isMember(TestEndpointUtils.vcellSupportUser)); // Should not have access to VCell support roles because random user does not have the support role BioModelInfo[] randomUserInfos = databaseServer.getBioModelInfos(randomUser, true); Assertions.assertEquals(0, randomUserInfos.length); + + // Random user has BioModel that admin can't access + databaseServer.saveBioModel(TestEndpointUtils.randomUser, new BigString(bioModelVCML), null); + infos = databaseServer.getBioModelInfos(adminUser, true); + Assertions.assertEquals(1, infos.length); + Assertions.assertTrue(infos[0].getVersion().getVersionKey().compareEqual(savedModel.getVersion().getVersionKey())); + infos = databaseServer.getBioModelInfos(randomUser, true); + Assertions.assertEquals(1, infos.length); + Assertions.assertFalse(savedModel.getVersion().getVersionKey().compareEqual(infos[0].getVersion().getVersionKey())); } @Test From cb15cb968abb5e827fd9fd55116d833ad34a201c Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Wed, 18 Jun 2025 10:58:47 -0400 Subject: [PATCH 10/13] Getter For VCell Support ID --- .../cbit/vcell/resource/PropertyLoader.java | 1 - ...tUpTasks.java => QuarkusStartUpTasks.java} | 12 ++++------ .../org/vcell/restq/auth/ACLSupportTest.java | 3 ++- .../java/cbit/sql/ServerStartUpTasks.java | 24 +++++++++++++++++++ .../cbit/vcell/modeldb/DatabasePolicySQL.java | 3 ++- 5 files changed, 33 insertions(+), 10 deletions(-) rename vcell-rest/src/main/java/org/vcell/restq/{StartUpTasks.java => QuarkusStartUpTasks.java} (63%) create mode 100644 vcell-server/src/main/java/cbit/sql/ServerStartUpTasks.java diff --git a/vcell-core/src/main/java/cbit/vcell/resource/PropertyLoader.java b/vcell-core/src/main/java/cbit/vcell/resource/PropertyLoader.java index 5d062c4336..d052573344 100644 --- a/vcell-core/src/main/java/cbit/vcell/resource/PropertyLoader.java +++ b/vcell-core/src/main/java/cbit/vcell/resource/PropertyLoader.java @@ -57,7 +57,6 @@ public static void setConfigProvider(VCellConfigProvider configProvider) { public static final String ADMINISTRATOR_ID = "2"; public static final String TESTACCOUNT_USERID = "vcellNagios"; public static final String VCELL_SUPPORT_USERID = "VCellSupport"; - public static final String vcellSupportId = record("vcell.user.support", ValueType.GEN); public static final String vcellServerIDProperty = record("vcell.server.id",ValueType.GEN); diff --git a/vcell-rest/src/main/java/org/vcell/restq/StartUpTasks.java b/vcell-rest/src/main/java/org/vcell/restq/QuarkusStartUpTasks.java similarity index 63% rename from vcell-rest/src/main/java/org/vcell/restq/StartUpTasks.java rename to vcell-rest/src/main/java/org/vcell/restq/QuarkusStartUpTasks.java index fb7c493124..795b63f70e 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/StartUpTasks.java +++ b/vcell-rest/src/main/java/org/vcell/restq/QuarkusStartUpTasks.java @@ -1,7 +1,7 @@ package org.vcell.restq; +import cbit.sql.ServerStartUpTasks; import cbit.vcell.modeldb.AdminDBTopLevel; -import cbit.vcell.resource.PropertyLoader; import io.quarkus.runtime.StartupEvent; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; @@ -15,18 +15,16 @@ import java.sql.SQLException; @ApplicationScoped -public class StartUpTasks { - private final static Logger logger = LogManager.getLogger(StartUpTasks.class); +public class QuarkusStartUpTasks { + private final static Logger logger = LogManager.getLogger(QuarkusStartUpTasks.class); @Inject AgroalConnectionFactory connectionFactory; public void onStartUp(@Observes StartupEvent ev) throws SQLException, DataAccessException { logger.info("Executing startup tasks"); - - AdminDBTopLevel adminDBTopLevel = new AdminDBTopLevel(connectionFactory); - User vcellSupport = adminDBTopLevel.getVCellSupportUser(true); - PropertyLoader.setProperty(PropertyLoader.vcellSupportId, vcellSupport.getID().toString()); + ServerStartUpTasks.executeStartUpTasks(connectionFactory); + logger.info("Startup tasks executed successfully"); } } diff --git a/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java b/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java index 0c11c81ddb..2725906b36 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/auth/ACLSupportTest.java @@ -1,5 +1,6 @@ package org.vcell.restq.auth; +import cbit.sql.ServerStartUpTasks; import cbit.vcell.biomodel.BioModel; import cbit.vcell.modeldb.AdminDBTopLevel; import cbit.vcell.modeldb.DatabaseServerImpl; @@ -132,6 +133,6 @@ public void testSpecialClaimsPeopleHave() throws SQLException, DataAccessExcepti @Test public void testVCellSupportIDGrabbing(){ - Assertions.assertEquals(PropertyLoader.getRequiredProperty(PropertyLoader.vcellSupportId), "4"); + Assertions.assertEquals(ServerStartUpTasks.getVCellSupportID(), "4"); } } diff --git a/vcell-server/src/main/java/cbit/sql/ServerStartUpTasks.java b/vcell-server/src/main/java/cbit/sql/ServerStartUpTasks.java new file mode 100644 index 0000000000..a6c2fc71e7 --- /dev/null +++ b/vcell-server/src/main/java/cbit/sql/ServerStartUpTasks.java @@ -0,0 +1,24 @@ +package cbit.sql; + +import cbit.vcell.modeldb.AdminDBTopLevel; +import org.vcell.db.ConnectionFactory; +import org.vcell.util.DataAccessException; +import org.vcell.util.document.User; + +import java.sql.SQLException; + +public class ServerStartUpTasks { + private static String vcellSupportID = null; + + + public static void executeStartUpTasks(ConnectionFactory connectionFactory) throws SQLException, DataAccessException { + AdminDBTopLevel adminDBTopLevel = new AdminDBTopLevel(connectionFactory); + User user = adminDBTopLevel.getVCellSupportUser(true); + vcellSupportID = user.getID().toString(); + } + + public static String getVCellSupportID() { + return vcellSupportID; + } + +} diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabasePolicySQL.java b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabasePolicySQL.java index 53fbde36fe..a2731400b0 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/DatabasePolicySQL.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/DatabasePolicySQL.java @@ -12,6 +12,7 @@ import java.util.Arrays; import java.util.List; +import cbit.sql.ServerStartUpTasks; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.vcell.db.DatabaseSyntax; @@ -306,7 +307,7 @@ static String getVTableDirectSelectClause(VersionTable vTable,User user) { String vcellSupportClause = ""; if (user instanceof SpecialUser specialUser && specialUser.isVCellSupport()){ - vcellSupportClause = " OR " + GroupTable.table.userRef.getQualifiedColName() + " = " + PropertyLoader.getRequiredProperty(PropertyLoader.vcellSupportId); + vcellSupportClause = " OR " + GroupTable.table.userRef.getQualifiedColName() + " = " + ServerStartUpTasks.getVCellSupportID(); } String sql = " ( "+ vTable.privacy.getQualifiedColName() + " = " + GroupTable.table.groupid.getQualifiedColName() + From 0895cce5bb3c47d00c9fb4a9db2681edd97e01a0 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Wed, 18 Jun 2025 11:04:18 -0400 Subject: [PATCH 11/13] Hashmap For User Creation SQL --- .../java/cbit/vcell/modeldb/UserDbDriver.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java index 1d44717d29..0465d6e264 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/UserDbDriver.java @@ -31,10 +31,8 @@ import java.math.BigDecimal; import java.security.SecureRandom; import java.sql.*; -import java.util.ArrayList; +import java.util.*; import java.util.Date; -import java.util.List; -import java.util.Random; /** * This type was created in VisualAge. @@ -158,25 +156,24 @@ public List getUserIdentitiesFromSubjectAndIssuer(Connection con, lg.trace(sql); } stmt = con.createStatement(); - ArrayList userIdentities = new ArrayList<>(); + HashMap userIdentities = new HashMap<>(); try { rset = stmt.executeQuery(sql); while (rset.next()) { BigDecimal userKey = rset.getBigDecimal(UserIdentityTable.userRef.getUnqualifiedColName()); String claim = rset.getString(SpecialUsersTable.table.special.getUnqualifiedColName()); - - int lastUserAdded = userIdentities.size()-1; - boolean sameUser = !userIdentities.isEmpty() && userIdentities.get(lastUserAdded).getId().equals(userKey); - if (sameUser && claim != null){ - userIdentities.get(lastUserAdded).getUserBuilder().addSpecial(SpecialUser.SPECIAL_CLAIM.fromDatabase(claim)); - } else{ + if (userIdentities.containsKey(userKey) && claim != null) { + userIdentities.get(userKey).getUserBuilder().addSpecial(SpecialUser.SPECIAL_CLAIM.fromDatabase(claim)); + } else if (userIdentities.containsKey(userKey)) { + throw new SQLException("Duplicate VCell user identity found."); + } else { String userID = rset.getString(UserTable.table.userid.getUnqualifiedColName()); SpecialUser.SpecialUserBuilder builder = new SpecialUser.SpecialUserBuilder(userID, new KeyValue(userKey)); if (claim != null){ builder.addSpecial(SpecialUser.SPECIAL_CLAIM.fromDatabase(claim)); } - userIdentities.add(new UserIdentityBuilder(userKey, builder, - subject, issuer, UserIdentityTable.table.getUserIdentityDate(rset))); + userIdentities.put(userKey, new UserIdentityBuilder(userKey, builder, subject, issuer, + UserIdentityTable.table.getUserIdentityDate(rset))); } } } finally { @@ -184,7 +181,7 @@ public List getUserIdentitiesFromSubjectAndIssuer(Connection con, } ArrayList identities = new ArrayList<>(); - for (UserIdentityBuilder userIdentityBuilder : userIdentities) { + for (UserIdentityBuilder userIdentityBuilder : userIdentities.values()) { identities.add(userIdentityBuilder.build()); } From ffcaa3dabadaffc2324beb73ebd0fab0ed0ad67e Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 19 Jun 2025 08:13:28 -0400 Subject: [PATCH 12/13] User Object For DTO Only --- python-restclient/.openapi-generator/FILES | 69 +++++- python-restclient/README.md | 1 - python-restclient/docs/User.md | 2 +- python-restclient/test/test_analyzed_file.py | 79 ------ .../test_analyzed_results_from_field_data.py | 79 ------ python-restclient/test/test_bio_model.py | 3 +- .../test/test_bio_model_context.py | 165 ------------- .../test/test_bio_model_resource_api.py | 33 ++- .../test/test_bio_model_summary.py | 28 +-- .../test/test_copy_field_data.py | 54 ---- .../test_create_field_data_from_simulation.py | 56 ----- .../test/test_external_data_identifier.py | 17 +- .../test/test_field_data_reference.py | 23 +- .../test/test_field_data_resource_api.py | 54 +++- .../test/test_field_data_save_results.py | 54 ---- .../test/test_geometry_summary.py | 5 +- python-restclient/test/test_group_access.py | 1 + .../test/test_group_access_all.py | 3 +- .../test/test_group_access_none.py | 3 +- .../test/test_group_access_some.py | 21 +- python-restclient/test/test_key_value.py | 53 ---- .../test/test_math_model_child_summary.py | 8 - .../test/test_math_model_resource_api.py | 6 + .../test/test_math_model_summary.py | 20 +- .../test/test_publication_info.py | 15 +- .../test/test_publication_resource_api.py | 2 +- python-restclient/test/test_save_bio_model.py | 57 ----- python-restclient/test/test_saved_results.py | 54 ---- python-restclient/test/test_shape.py | 87 ------- .../test/test_simulation_job_status_record.py | 13 +- .../test/test_solver_resource_api.py | 11 +- .../test/test_spatial_resource_api.py | 39 --- python-restclient/test/test_special_user.py | 60 ----- python-restclient/test/test_status_message.py | 13 +- python-restclient/test/test_user.py | 8 +- .../test/test_v_cell_software_version.py | 1 - .../test/test_vc_simulation_identifier.py | 13 +- python-restclient/test/test_version.py | 32 +-- python-restclient/vcell_client/__init__.py | 1 - .../vcell_client/models/__init__.py | 1 - .../vcell_client/models/special_user.py | 99 -------- python-restclient/vcell_client/models/user.py | 59 ++--- tools/openapi.yaml | 28 +-- .../org/vcell/util/document/SpecialUser.java | 6 +- .../java/org/vcell/util/document/User.java | 11 +- vcell-restclient/.openapi-generator/FILES | 2 - vcell-restclient/README.md | 1 - vcell-restclient/api/openapi.yaml | 90 ++++--- vcell-restclient/docs/User.md | 2 +- .../restclient/api/FieldDataResourceApi.java | 15 +- .../vcell/restclient/model/SpecialUser.java | 233 ------------------ .../java/org/vcell/restclient/model/User.java | 119 +++++---- .../restclient/utils/DtoModelTransforms.java | 16 +- .../restclient/model/SpecialUserTest.java | 91 ------- .../modules/openapi/.openapi-generator/FILES | 1 - .../app/core/modules/openapi/model/models.ts | 1 - .../modules/openapi/model/special-user.ts | 20 -- .../app/core/modules/openapi/model/user.ts | 3 +- 58 files changed, 402 insertions(+), 1639 deletions(-) delete mode 100644 python-restclient/test/test_analyzed_file.py delete mode 100644 python-restclient/test/test_analyzed_results_from_field_data.py delete mode 100644 python-restclient/test/test_bio_model_context.py delete mode 100644 python-restclient/test/test_copy_field_data.py delete mode 100644 python-restclient/test/test_create_field_data_from_simulation.py delete mode 100644 python-restclient/test/test_field_data_save_results.py delete mode 100644 python-restclient/test/test_key_value.py delete mode 100644 python-restclient/test/test_save_bio_model.py delete mode 100644 python-restclient/test/test_saved_results.py delete mode 100644 python-restclient/test/test_shape.py delete mode 100644 python-restclient/test/test_spatial_resource_api.py delete mode 100644 python-restclient/test/test_special_user.py delete mode 100644 python-restclient/vcell_client/models/special_user.py delete mode 100644 vcell-restclient/src/main/java/org/vcell/restclient/model/SpecialUser.java delete mode 100644 vcell-restclient/src/test/java/org/vcell/restclient/model/SpecialUserTest.java delete mode 100644 webapp-ng/src/app/core/modules/openapi/model/special-user.ts diff --git a/python-restclient/.openapi-generator/FILES b/python-restclient/.openapi-generator/FILES index 270f2c7cbd..60e115c1aa 100644 --- a/python-restclient/.openapi-generator/FILES +++ b/python-restclient/.openapi-generator/FILES @@ -52,7 +52,6 @@ docs/SimulationResourceApi.md docs/SimulationStatusPersistentRecord.md docs/SolverResourceApi.md docs/SourceModel.md -docs/SpecialUser.md docs/Status.md docs/StatusMessage.md docs/User.md @@ -70,6 +69,73 @@ docs/VariableType.md docs/Version.md docs/VersionFlag.md test/__init__.py +test/test_acces_token_representation_record.py +test/test_admin_resource_api.py +test/test_application_info.py +test/test_batch_system_type.py +test/test_bio_model.py +test/test_bio_model_child_summary.py +test/test_bio_model_resource_api.py +test/test_bio_model_summary.py +test/test_biomodel_ref.py +test/test_data_identifier.py +test/test_detailed_state.py +test/test_domain.py +test/test_extent.py +test/test_external_data_identifier.py +test/test_field_data.py +test/test_field_data_reference.py +test/test_field_data_resource_api.py +test/test_field_data_saved_results.py +test/test_field_data_shape.py +test/test_geometry_resource_api.py +test/test_geometry_summary.py +test/test_group_access.py +test/test_group_access_all.py +test/test_group_access_none.py +test/test_group_access_some.py +test/test_hello_world_api.py +test/test_hello_world_message.py +test/test_htc_job_id.py +test/test_i_size.py +test/test_identity.py +test/test_math_model_child_summary.py +test/test_math_model_resource_api.py +test/test_math_model_summary.py +test/test_math_type.py +test/test_mathmodel_ref.py +test/test_model_type.py +test/test_origin.py +test/test_publication.py +test/test_publication_info.py +test/test_publication_resource_api.py +test/test_scheduler_status.py +test/test_simulation_execution_status_record.py +test/test_simulation_job_status_record.py +test/test_simulation_message.py +test/test_simulation_queue_entry_status_record.py +test/test_simulation_queue_id.py +test/test_simulation_resource_api.py +test/test_simulation_status_persistent_record.py +test/test_solver_resource_api.py +test/test_source_model.py +test/test_specialclaim.py +test/test_status.py +test/test_status_message.py +test/test_user.py +test/test_user_identity_json_safe.py +test/test_user_login_info_for_mapping.py +test/test_user_registration_info.py +test/test_users_resource_api.py +test/test_v_cell_http_error.py +test/test_v_cell_site.py +test/test_v_cell_software_version.py +test/test_variable_domain.py +test/test_variable_type.py +test/test_vc_document_type.py +test/test_vc_simulation_identifier.py +test/test_version.py +test/test_version_flag.py tox.ini vcell_client/__init__.py vcell_client/api/__init__.py @@ -129,7 +195,6 @@ vcell_client/models/simulation_queue_entry_status_record.py vcell_client/models/simulation_queue_id.py vcell_client/models/simulation_status_persistent_record.py vcell_client/models/source_model.py -vcell_client/models/special_user.py vcell_client/models/specialclaim.py vcell_client/models/status.py vcell_client/models/status_message.py diff --git a/python-restclient/README.md b/python-restclient/README.md index c4d28d7cb2..013b71f676 100644 --- a/python-restclient/README.md +++ b/python-restclient/README.md @@ -182,7 +182,6 @@ Class | Method | HTTP request | Description - [SimulationQueueID](docs/SimulationQueueID.md) - [SimulationStatusPersistentRecord](docs/SimulationStatusPersistentRecord.md) - [SourceModel](docs/SourceModel.md) - - [SpecialUser](docs/SpecialUser.md) - [Status](docs/Status.md) - [StatusMessage](docs/StatusMessage.md) - [User](docs/User.md) diff --git a/python-restclient/docs/User.md b/python-restclient/docs/User.md index 26e3715e1b..6df2870c42 100644 --- a/python-restclient/docs/User.md +++ b/python-restclient/docs/User.md @@ -4,9 +4,9 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**is_special** | **str** | | [default to 'no'] **user_name** | **str** | | [optional] **key** | **str** | | [optional] +**my_specials** | [**List[SPECIALCLAIM]**](SPECIALCLAIM.md) | | [optional] ## Example diff --git a/python-restclient/test/test_analyzed_file.py b/python-restclient/test/test_analyzed_file.py deleted file mode 100644 index e967329422..0000000000 --- a/python-restclient/test/test_analyzed_file.py +++ /dev/null @@ -1,79 +0,0 @@ -# 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.analyzed_file import AnalyzedFile - -class TestAnalyzedFile(unittest.TestCase): - """AnalyzedFile unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> AnalyzedFile: - """Test AnalyzedFile - 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 `AnalyzedFile` - """ - model = AnalyzedFile() - if include_optional: - return AnalyzedFile( - short_spec_data = [ - [ - [ - 56 - ] - ] - ], - var_names = [ - '' - ], - times = [ - 1.337 - ], - origin = vcell_client.models.origin.Origin( - x = 1.337, - y = 1.337, - z = 1.337, ), - extent = vcell_client.models.extent.Extent( - x = 1.337, - y = 1.337, - z = 1.337, ), - isize = vcell_client.models.i_size.ISize( - x = 56, - y = 56, - z = 56, ), - annotation = '', - name = '' - ) - else: - return AnalyzedFile( - ) - """ - - def testAnalyzedFile(self): - """Test AnalyzedFile""" - # 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_analyzed_results_from_field_data.py b/python-restclient/test/test_analyzed_results_from_field_data.py deleted file mode 100644 index 1d6a48aec4..0000000000 --- a/python-restclient/test/test_analyzed_results_from_field_data.py +++ /dev/null @@ -1,79 +0,0 @@ -# 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.analyzed_results_from_field_data import AnalyzedResultsFromFieldData - -class TestAnalyzedResultsFromFieldData(unittest.TestCase): - """AnalyzedResultsFromFieldData unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> AnalyzedResultsFromFieldData: - """Test AnalyzedResultsFromFieldData - 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 `AnalyzedResultsFromFieldData` - """ - model = AnalyzedResultsFromFieldData() - if include_optional: - return AnalyzedResultsFromFieldData( - short_spec_data = [ - [ - [ - 56 - ] - ] - ], - var_names = [ - '' - ], - times = [ - 1.337 - ], - origin = vcell_client.models.origin.Origin( - x = 1.337, - y = 1.337, - z = 1.337, ), - extent = vcell_client.models.extent.Extent( - x = 1.337, - y = 1.337, - z = 1.337, ), - isize = vcell_client.models.i_size.ISize( - x = 56, - y = 56, - z = 56, ), - annotation = '', - name = '' - ) - else: - return AnalyzedResultsFromFieldData( - ) - """ - - def testAnalyzedResultsFromFieldData(self): - """Test AnalyzedResultsFromFieldData""" - # 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_bio_model.py b/python-restclient/test/test_bio_model.py index 5232c011f8..6c028744f2 100644 --- a/python-restclient/test/test_bio_model.py +++ b/python-restclient/test/test_bio_model.py @@ -50,8 +50,7 @@ def make_instance(self, include_optional) -> BioModel: owner_name = '', owner_key = '', simulation_key_list = [ - vcell_client.models.key_value.KeyValue( - value = 1.337, ) + '' ], applications = [ vcell_client.models.application.Application() diff --git a/python-restclient/test/test_bio_model_context.py b/python-restclient/test/test_bio_model_context.py deleted file mode 100644 index f84a68a616..0000000000 --- a/python-restclient/test/test_bio_model_context.py +++ /dev/null @@ -1,165 +0,0 @@ -# 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.bio_model_context import BioModelContext - -class TestBioModelContext(unittest.TestCase): - """BioModelContext unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> BioModelContext: - """Test BioModelContext - 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 `BioModelContext` - """ - model = BioModelContext() - if include_optional: - return BioModelContext( - version = vcell_client.models.version.Version( - version_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - version_name = '', - version_owner = vcell_client.models.user.User( - user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), ), - version_group_access = vcell_client.models.group_access.GroupAccess( - groupid = 1.337, - description = '', ), - version_branch_point_ref = , - version_branch_id = 1.337, - version_date = 'Thu Mar 10 00:00:00 UTC 2022', - version_flag = vcell_client.models.version_flag.VersionFlag( - int_value = 56, - archived = True, - current = True, - published = True, ), - version_annot = '', - annot = '', - branch_id = 1.337, - branch_point_ref_key = , - date = 'Thu Mar 10 00:00:00 UTC 2022', - flag = vcell_client.models.version_flag.VersionFlag( - int_value = 56, - archived = True, - current = True, - published = True, ), - group_access = vcell_client.models.group_access.GroupAccess( - groupid = 1.337, - description = '', ), - name = '', - owner = vcell_client.models.user.User( - user_name = '', ), ), - summary = vcell_client.models.bio_model_child_summary.BioModelChildSummary( - sc_names = [ - '' - ], - sc_annots = [ - '' - ], - geo_names = [ - '' - ], - geo_dims = [ - 56 - ], - app_types = [ - 'RuleBased' - ], - sim_names = [ - [ - '' - ] - ], - sim_annots = [ - [ - '' - ] - ], - geometry_dimensions = [ - 56 - ], - geometry_names = [ - '' - ], - simulation_context_annotations = [ - '' - ], - simulation_context_names = [ - '' - ], - application_info = [ - vcell_client.models.application_info.ApplicationInfo( - name = '', - type = 'RuleBased', - dimensions = 56, - geometry_name = '', ) - ], ), - publication_information = [ - vcell_client.models.publication_info.PublicationInfo( - publication_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - version_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - title = '', - authors = [ - '' - ], - citation = '', - pubmedid = '', - doi = '', - url = '', - pubdate = 'Thu Mar 10 00:00:00 UTC 2022', - vc_document_type = 'BIOMODEL_DOC', - user = vcell_client.models.user.User( - user_name = '', - key = , ), - the_hash_code = 56, - pub_date = 'Thu Mar 10 00:00:00 UTC 2022', ) - ], - v_cell_software_version = vcell_client.models.v_cell_software_version.VCellSoftwareVersion( - software_version_string = '', - vcell_site = 'alpha', - build_number = '', - version_number = '', - major_version = 56, - minor_version = 56, - patch_version = 56, - build_int = 56, - site = 'alpha', - description = '', ) - ) - else: - return BioModelContext( - ) - """ - - def testBioModelContext(self): - """Test BioModelContext""" - # 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_bio_model_resource_api.py b/python-restclient/test/test_bio_model_resource_api.py index fea6ab89d1..fba7b83330 100644 --- a/python-restclient/test/test_bio_model_resource_api.py +++ b/python-restclient/test/test_bio_model_resource_api.py @@ -34,17 +34,38 @@ def test_delete_bio_model(self) -> None: """ pass - def test_get_biomodel_by_id(self) -> None: - """Test case for get_biomodel_by_id + def test_get_bio_model(self) -> None: + """Test case for get_bio_model - Get BioModel information in JSON format by ID. + Get BioModel. """ pass - def test_upload_bio_model(self) -> None: - """Test case for upload_bio_model + def test_get_bio_model_summaries(self) -> None: + """Test case for get_bio_model_summaries - Upload the BioModel to VCell database. Returns BioModel ID. + Return BioModel summaries. + """ + pass + + def test_get_bio_model_summary(self) -> None: + """Test case for get_bio_model_summary + + All of the text based information about a BioModel (summary, version, publication status, etc...), but not the actual BioModel itself. + """ + pass + + def test_get_bio_model_vcml(self) -> None: + """Test case for get_bio_model_vcml + + Get the BioModel in VCML format. + """ + pass + + def test_save_bio_model(self) -> None: + """Test case for save_bio_model + + Save's the given BioModel. Optional parameters of name and simulations to update due to math changes. Returns saved BioModel as VCML. """ pass diff --git a/python-restclient/test/test_bio_model_summary.py b/python-restclient/test/test_bio_model_summary.py index 2e72fbfb34..36d9e7ed51 100644 --- a/python-restclient/test/test_bio_model_summary.py +++ b/python-restclient/test/test_bio_model_summary.py @@ -38,13 +38,11 @@ def make_instance(self, include_optional) -> BioModelSummary: if include_optional: return BioModelSummary( version = vcell_client.models.version.Version( - version_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + version_key = '', annot = '', branch_id = 1.337, - branch_point_ref_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - date = 'Thu Mar 10 00:00:00 UTC 2022', + branch_point_ref_key = '', + date = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), flag = vcell_client.models.version_flag.VersionFlag( version_flag = 56, int_value = 56, @@ -57,7 +55,10 @@ def make_instance(self, include_optional) -> BioModelSummary: name = '', owner = vcell_client.models.user.User( user_name = '', - key = , ), ), + key = '', + my_specials = [ + 'admins' + ], ), ), summary = vcell_client.models.bio_model_child_summary.BioModelChildSummary( sc_names = [ '' @@ -105,10 +106,8 @@ def make_instance(self, include_optional) -> BioModelSummary: ], ), publication_information = [ vcell_client.models.publication_info.PublicationInfo( - publication_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - version_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + publication_key = '', + version_key = '', title = '', authors = [ '' @@ -121,9 +120,11 @@ def make_instance(self, include_optional) -> BioModelSummary: vc_document_type = 'BIOMODEL_DOC', user = vcell_client.models.user.User( user_name = '', - key = , ), - the_hash_code = 56, - pub_date = 'Thu Mar 10 00:00:00 UTC 2022', ) + key = '', + my_specials = [ + 'admins' + ], ), + the_hash_code = 56, ) ], v_cell_software_version = vcell_client.models.v_cell_software_version.VCellSoftwareVersion( software_version_string = '', @@ -134,7 +135,6 @@ def make_instance(self, include_optional) -> BioModelSummary: minor_version = 56, patch_version = 56, build_int = 56, - site = 'alpha', description = '', ) ) else: diff --git a/python-restclient/test/test_copy_field_data.py b/python-restclient/test/test_copy_field_data.py deleted file mode 100644 index bfda38faa6..0000000000 --- a/python-restclient/test/test_copy_field_data.py +++ /dev/null @@ -1,54 +0,0 @@ -# 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.copy_field_data import CopyFieldData - -class TestCopyFieldData(unittest.TestCase): - """CopyFieldData unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> CopyFieldData: - """Test CopyFieldData - 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 `CopyFieldData` - """ - model = CopyFieldData() - if include_optional: - return CopyFieldData( - model_id = '', - model_type = 'BIOMODEL' - ) - else: - return CopyFieldData( - ) - """ - - def testCopyFieldData(self): - """Test CopyFieldData""" - # 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_create_field_data_from_simulation.py b/python-restclient/test/test_create_field_data_from_simulation.py deleted file mode 100644 index 5cb79bdf6e..0000000000 --- a/python-restclient/test/test_create_field_data_from_simulation.py +++ /dev/null @@ -1,56 +0,0 @@ -# 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.create_field_data_from_simulation import CreateFieldDataFromSimulation - -class TestCreateFieldDataFromSimulation(unittest.TestCase): - """CreateFieldDataFromSimulation unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> CreateFieldDataFromSimulation: - """Test CreateFieldDataFromSimulation - 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 `CreateFieldDataFromSimulation` - """ - model = CreateFieldDataFromSimulation() - if include_optional: - return CreateFieldDataFromSimulation( - sim_reference = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - job_index = 56, - new_field_data_name = '' - ) - else: - return CreateFieldDataFromSimulation( - ) - """ - - def testCreateFieldDataFromSimulation(self): - """Test CreateFieldDataFromSimulation""" - # 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_external_data_identifier.py b/python-restclient/test/test_external_data_identifier.py index b6f749ab0d..e7d07fb26d 100644 --- a/python-restclient/test/test_external_data_identifier.py +++ b/python-restclient/test/test_external_data_identifier.py @@ -37,21 +37,18 @@ def make_instance(self, include_optional) -> ExternalDataIdentifier: model = ExternalDataIdentifier() if include_optional: return ExternalDataIdentifier( - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + key = '', owner = vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - name = '', - test_account = True, ), + key = '', + my_specials = [ + 'admins' + ], ), name = '', job_index = 56, - simulation_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + simulation_key = '', parameter_scan_type = True, - data_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ) + data_key = '' ) else: return ExternalDataIdentifier( diff --git a/python-restclient/test/test_field_data_reference.py b/python-restclient/test/test_field_data_reference.py index a2db444a9a..d1237dbfb0 100644 --- a/python-restclient/test/test_field_data_reference.py +++ b/python-restclient/test/test_field_data_reference.py @@ -37,23 +37,22 @@ def make_instance(self, include_optional) -> FieldDataReference: model = FieldDataReference() if include_optional: return FieldDataReference( - external_data_identifier = vcell_client.models.external_data_identifier.ExternalDataIdentifier( - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + field_data_id = vcell_client.models.external_data_identifier.ExternalDataIdentifier( + key = '', owner = vcell_client.models.user.User( user_name = '', - name = '', - test_account = True, ), + key = '', + my_specials = [ + 'admins' + ], ), name = '', job_index = 56, - simulation_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + simulation_key = '', parameter_scan_type = True, - data_key = , ), - external_data_annotation = '', - external_data_id_sim_ref = [ - vcell_client.models.key_value.KeyValue( - value = 1.337, ) + data_key = '', ), + annotation = '', + simulations_referencing_this_id = [ + '' ] ) else: diff --git a/python-restclient/test/test_field_data_resource_api.py b/python-restclient/test/test_field_data_resource_api.py index 223c7efcba..6fd18c0c9f 100644 --- a/python-restclient/test/test_field_data_resource_api.py +++ b/python-restclient/test/test_field_data_resource_api.py @@ -27,38 +27,66 @@ def setUp(self) -> None: def tearDown(self) -> None: pass - def test_analyze_field_data_file(self) -> None: - """Test case for analyze_field_data_file + def test_advanced_create(self) -> None: + """Test case for advanced_create - Analyze the field data from the uploaded file. Filenames must be lowercase alphanumeric, and can contain underscores. + Create Field Data with granular detail in one request.The following files are accepted: .tif and .zip. """ pass - def test_create_field_data_from_analyzed_file(self) -> None: - """Test case for create_field_data_from_analyzed_file + def test_analyze_file(self) -> None: + """Test case for analyze_file - Take the analyzed results of the field data, modify it to your liking, then save it on the server. + 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. """ pass - def test_delete_field_data(self) -> None: - """Test case for delete_field_data + def test_copy_models_field_data(self) -> None: + """Test case for copy_models_field_data + + Copy all existing field data from a BioModel/MathModel that you have access to, but don't own. + """ + pass + + def test_create_from_file(self) -> None: + """Test case for create_from_file + + Submit a .zip or .tif file that converts into field data, with all defaults derived from the file submitted. + """ + pass + + def test_create_from_simulation(self) -> None: + """Test case for create_from_simulation + + Create new field data from existing simulation results. + """ + pass + + def test_delete(self) -> None: + """Test case for delete Delete the selected field data. """ pass - def test_get_all_field_data_ids(self) -> None: - """Test case for get_all_field_data_ids + def test_get_all_ids(self) -> None: + """Test case for get_all_ids Get all of the ids used to identify, and retrieve field data. """ pass - def test_get_field_data_shape_from_id(self) -> None: - """Test case for get_field_data_shape_from_id + def test_get_shape_from_id(self) -> None: + """Test case for get_shape_from_id + + Get the shape of the field data. That is it's size, origin, extent, times, and data identifiers. + """ + pass + + def test_save(self) -> None: + """Test case for save - Get the shape of the field data. That is it's size, origin, extent, and data identifiers. + Take the generated field data, and save it to the server. User may adjust the analyzed file before uploading to edit defaults. """ pass diff --git a/python-restclient/test/test_field_data_save_results.py b/python-restclient/test/test_field_data_save_results.py deleted file mode 100644 index 487181bb30..0000000000 --- a/python-restclient/test/test_field_data_save_results.py +++ /dev/null @@ -1,54 +0,0 @@ -# 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.field_data_save_results import FieldDataSaveResults - -class TestFieldDataSaveResults(unittest.TestCase): - """FieldDataSaveResults unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> FieldDataSaveResults: - """Test FieldDataSaveResults - 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 `FieldDataSaveResults` - """ - model = FieldDataSaveResults() - if include_optional: - return FieldDataSaveResults( - field_data_name = '', - field_data_id = '' - ) - else: - return FieldDataSaveResults( - ) - """ - - def testFieldDataSaveResults(self): - """Test FieldDataSaveResults""" - # 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_geometry_summary.py b/python-restclient/test/test_geometry_summary.py index a356123ac0..d7b79e5b24 100644 --- a/python-restclient/test/test_geometry_summary.py +++ b/python-restclient/test/test_geometry_summary.py @@ -65,7 +65,10 @@ def make_instance(self, include_optional) -> GeometrySummary: name = '', owner = vcell_client.models.user.User( user_name = '', - key = '', ), ), + key = '', + my_specials = [ + 'admins' + ], ), ), software_version = vcell_client.models.v_cell_software_version.VCellSoftwareVersion( software_version_string = '', vcell_site = 'alpha', diff --git a/python-restclient/test/test_group_access.py b/python-restclient/test/test_group_access.py index 164ba10d93..81bf4e831a 100644 --- a/python-restclient/test/test_group_access.py +++ b/python-restclient/test/test_group_access.py @@ -42,6 +42,7 @@ def make_instance(self, include_optional) -> GroupAccess: ) else: return GroupAccess( + groupid = 1.337, ) """ diff --git a/python-restclient/test/test_group_access_all.py b/python-restclient/test/test_group_access_all.py index 2feb3f107d..a8fa0ae27f 100644 --- a/python-restclient/test/test_group_access_all.py +++ b/python-restclient/test/test_group_access_all.py @@ -37,11 +37,12 @@ def make_instance(self, include_optional) -> GroupAccessAll: model = GroupAccessAll() if include_optional: return GroupAccessAll( - groupid = 1.337, + type = 'GroupAccessAll', description = '' ) else: return GroupAccessAll( + type = 'GroupAccessAll', ) """ diff --git a/python-restclient/test/test_group_access_none.py b/python-restclient/test/test_group_access_none.py index a1c363f63a..172eb5f3fd 100644 --- a/python-restclient/test/test_group_access_none.py +++ b/python-restclient/test/test_group_access_none.py @@ -37,11 +37,12 @@ def make_instance(self, include_optional) -> GroupAccessNone: model = GroupAccessNone() if include_optional: return GroupAccessNone( - groupid = 1.337, + type = 'GroupAccessNone', description = '' ) else: return GroupAccessNone( + type = 'GroupAccessNone', ) """ diff --git a/python-restclient/test/test_group_access_some.py b/python-restclient/test/test_group_access_some.py index 6991039cf9..c68cd34eed 100644 --- a/python-restclient/test/test_group_access_some.py +++ b/python-restclient/test/test_group_access_some.py @@ -37,13 +37,15 @@ def make_instance(self, include_optional) -> GroupAccessSome: model = GroupAccessSome() if include_optional: return GroupAccessSome( - groupid = 1.337, + type = 'GroupAccessSome', hash = 1.337, group_members = [ vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), ) + key = '', + my_specials = [ + 'admins' + ], ) ], hidden_members = [ True @@ -52,18 +54,23 @@ def make_instance(self, include_optional) -> GroupAccessSome: hidden_group_members = [ vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), ) + key = '', + my_specials = [ + 'admins' + ], ) ], normal_group_members = [ vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), ) + key = '', + my_specials = [ + 'admins' + ], ) ] ) else: return GroupAccessSome( + type = 'GroupAccessSome', ) """ diff --git a/python-restclient/test/test_key_value.py b/python-restclient/test/test_key_value.py deleted file mode 100644 index 9819b1e4d2..0000000000 --- a/python-restclient/test/test_key_value.py +++ /dev/null @@ -1,53 +0,0 @@ -# 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.key_value import KeyValue - -class TestKeyValue(unittest.TestCase): - """KeyValue unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> KeyValue: - """Test KeyValue - 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 `KeyValue` - """ - model = KeyValue() - if include_optional: - return KeyValue( - value = 1.337 - ) - else: - return KeyValue( - ) - """ - - def testKeyValue(self): - """Test KeyValue""" - # 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_math_model_child_summary.py b/python-restclient/test/test_math_model_child_summary.py index 52edbca374..fafe01d9de 100644 --- a/python-restclient/test/test_math_model_child_summary.py +++ b/python-restclient/test/test_math_model_child_summary.py @@ -37,14 +37,6 @@ def make_instance(self, include_optional) -> MathModelChildSummary: model = MathModelChildSummary() if include_optional: return MathModelChildSummary( - geo_name = '', - geo_dim = 56, - sim_names = [ - '' - ], - sim_annots = [ - '' - ], model_type = 'RuleBased', geometry_dimension = 56, geometry_name = '', diff --git a/python-restclient/test/test_math_model_resource_api.py b/python-restclient/test/test_math_model_resource_api.py index 5b0d8f405a..9098d2872b 100644 --- a/python-restclient/test/test_math_model_resource_api.py +++ b/python-restclient/test/test_math_model_resource_api.py @@ -39,6 +39,12 @@ def test_get_summaries(self) -> None: """ pass + def test_get_summary(self) -> None: + """Test case for get_summary + + """ + pass + def test_get_vcml(self) -> None: """Test case for get_vcml diff --git a/python-restclient/test/test_math_model_summary.py b/python-restclient/test/test_math_model_summary.py index 71cbaf1741..de1c880999 100644 --- a/python-restclient/test/test_math_model_summary.py +++ b/python-restclient/test/test_math_model_summary.py @@ -55,17 +55,12 @@ def make_instance(self, include_optional) -> MathModelSummary: name = '', owner = vcell_client.models.user.User( user_name = '', - key = '', ), ), + key = '', + my_specials = [ + 'admins' + ], ), ), key_value = '', - child_summary = vcell_client.models.math_model_child_summary.MathModelChildSummary( - geo_name = '', - geo_dim = 56, - sim_names = [ - '' - ], - sim_annots = [ - '' - ], + model_info = vcell_client.models.math_model_child_summary.MathModelChildSummary( model_type = 'RuleBased', geometry_dimension = 56, geometry_name = '', @@ -101,7 +96,10 @@ def make_instance(self, include_optional) -> MathModelSummary: vc_document_type = 'BIOMODEL_DOC', user = vcell_client.models.user.User( user_name = '', - key = '', ), + key = '', + my_specials = [ + 'admins' + ], ), the_hash_code = 56, ) ], annotated_functions = '' diff --git a/python-restclient/test/test_publication_info.py b/python-restclient/test/test_publication_info.py index 70a958a195..6c13a5dedd 100644 --- a/python-restclient/test/test_publication_info.py +++ b/python-restclient/test/test_publication_info.py @@ -37,10 +37,8 @@ def make_instance(self, include_optional) -> PublicationInfo: model = PublicationInfo() if include_optional: return PublicationInfo( - publication_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - version_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + publication_key = '', + version_key = '', title = '', authors = [ '' @@ -53,10 +51,11 @@ def make_instance(self, include_optional) -> PublicationInfo: vc_document_type = 'BIOMODEL_DOC', user = vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), ), - the_hash_code = 56, - pub_date = 'Thu Mar 10 00:00:00 UTC 2022' + key = '', + my_specials = [ + 'admins' + ], ), + the_hash_code = 56 ) else: return PublicationInfo( diff --git a/python-restclient/test/test_publication_resource_api.py b/python-restclient/test/test_publication_resource_api.py index 1cb44ec008..87131a61c5 100644 --- a/python-restclient/test/test_publication_resource_api.py +++ b/python-restclient/test/test_publication_resource_api.py @@ -58,7 +58,7 @@ def test_get_publications(self) -> None: def test_update_publication(self) -> None: """Test case for update_publication - Create publication + Update publication """ pass diff --git a/python-restclient/test/test_save_bio_model.py b/python-restclient/test/test_save_bio_model.py deleted file mode 100644 index 7e0947b903..0000000000 --- a/python-restclient/test/test_save_bio_model.py +++ /dev/null @@ -1,57 +0,0 @@ -# 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.save_bio_model import SaveBioModel - -class TestSaveBioModel(unittest.TestCase): - """SaveBioModel unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> SaveBioModel: - """Test SaveBioModel - 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 `SaveBioModel` - """ - model = SaveBioModel() - if include_optional: - return SaveBioModel( - bio_model_xml = '', - name = '', - sims_requiring_updates = [ - '' - ] - ) - else: - return SaveBioModel( - ) - """ - - def testSaveBioModel(self): - """Test SaveBioModel""" - # 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_saved_results.py b/python-restclient/test/test_saved_results.py deleted file mode 100644 index 938db18037..0000000000 --- a/python-restclient/test/test_saved_results.py +++ /dev/null @@ -1,54 +0,0 @@ -# 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.saved_results import SavedResults - -class TestSavedResults(unittest.TestCase): - """SavedResults unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> SavedResults: - """Test SavedResults - 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 `SavedResults` - """ - model = SavedResults() - if include_optional: - return SavedResults( - field_data_name = '', - field_data_id = '' - ) - else: - return SavedResults( - ) - """ - - def testSavedResults(self): - """Test SavedResults""" - # 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_shape.py b/python-restclient/test/test_shape.py deleted file mode 100644 index f50b9b6316..0000000000 --- a/python-restclient/test/test_shape.py +++ /dev/null @@ -1,87 +0,0 @@ -# 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.shape import Shape - -class TestShape(unittest.TestCase): - """Shape unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> Shape: - """Test Shape - 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 `Shape` - """ - model = Shape() - if include_optional: - return Shape( - extent = vcell_client.models.extent.Extent( - x = 1.337, - y = 1.337, - z = 1.337, ), - origin = vcell_client.models.origin.Origin( - x = 1.337, - y = 1.337, - z = 1.337, ), - isize = vcell_client.models.i_size.ISize( - x = 56, - y = 56, - z = 56, ), - data_identifier = [ - vcell_client.models.data_identifier.DataIdentifier( - name = '', - display_name = '', - variable_type = vcell_client.models.variable_type.VariableType( - type = 56, - variable_domain = 'VARIABLEDOMAIN_POSTPROCESSING', - name = '', - units = '', - label = '', - legacy_warn = True, - default_label = '', - default_units = '', - type_name = '', ), - domain = vcell_client.models.domain.Domain( - name = '', ), - b_function = True, - function = True, - visible = True, ) - ], - times = [ - 1.337 - ] - ) - else: - return Shape( - ) - """ - - def testShape(self): - """Test Shape""" - # 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_simulation_job_status_record.py b/python-restclient/test/test_simulation_job_status_record.py index b1d727596e..cf73b22808 100644 --- a/python-restclient/test/test_simulation_job_status_record.py +++ b/python-restclient/test/test_simulation_job_status_record.py @@ -39,15 +39,14 @@ def make_instance(self, include_optional) -> SimulationJobStatusRecord: return SimulationJobStatusRecord( field_time_data_stamp = '2022-03-10T16:15:50Z', field_vc_sim_id = vcell_client.models.vc_simulation_identifier.VCSimulationIdentifier( - simulation_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + simulation_key = '', owner = vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - name = '', - test_account = True, ), - i_d = '', ), + key = '', + my_specials = [ + 'admins' + ], ), + id = '', ), field_submit_date = '2022-03-10T16:15:50Z', field_scheduler_status = 'WAITING', field_simulation_message = vcell_client.models.simulation_message.SimulationMessage( diff --git a/python-restclient/test/test_solver_resource_api.py b/python-restclient/test/test_solver_resource_api.py index 6916ad57ad..e6a0f7e63b 100644 --- a/python-restclient/test/test_solver_resource_api.py +++ b/python-restclient/test/test_solver_resource_api.py @@ -27,8 +27,15 @@ def setUp(self) -> None: def tearDown(self) -> None: pass - def test_get_fv_solver_input(self) -> None: - """Test case for get_fv_solver_input + def test_get_fv_solver_input_from_sbml(self) -> None: + """Test case for get_fv_solver_input_from_sbml + + Retrieve finite volume input from SBML spatial model. + """ + pass + + def test_get_fv_solver_input_from_vcml(self) -> None: + """Test case for get_fv_solver_input_from_vcml Retrieve finite volume input from SBML spatial model. """ diff --git a/python-restclient/test/test_spatial_resource_api.py b/python-restclient/test/test_spatial_resource_api.py deleted file mode 100644 index 24bf0d3c22..0000000000 --- a/python-restclient/test/test_spatial_resource_api.py +++ /dev/null @@ -1,39 +0,0 @@ -# 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 - -from vcell_client.api.spatial_resource_api import SpatialResourceApi - - -class TestSpatialResourceApi(unittest.TestCase): - """SpatialResourceApi unit test stubs""" - - def setUp(self) -> None: - self.api = SpatialResourceApi() - - def tearDown(self) -> None: - pass - - def test_retrieve_finite_volume_input_from_spatial_model(self) -> None: - """Test case for retrieve_finite_volume_input_from_spatial_model - - Retrieve finite volume input from spatial model - """ - pass - - -if __name__ == '__main__': - unittest.main() diff --git a/python-restclient/test/test_special_user.py b/python-restclient/test/test_special_user.py deleted file mode 100644 index b4d8d98bfe..0000000000 --- a/python-restclient/test/test_special_user.py +++ /dev/null @@ -1,60 +0,0 @@ -# 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.special_user import SpecialUser - -class TestSpecialUser(unittest.TestCase): - """SpecialUser unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> SpecialUser: - """Test SpecialUser - 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 `SpecialUser` - """ - model = SpecialUser() - if include_optional: - return SpecialUser( - user_name = '', - key = '', - my_specials = [ - 'admins' - ], - admin = True, - publisher = True, - v_cell_support = True - ) - else: - return SpecialUser( - ) - """ - - def testSpecialUser(self): - """Test SpecialUser""" - # 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_status_message.py b/python-restclient/test/test_status_message.py index 48f6fa991a..b0126f366d 100644 --- a/python-restclient/test/test_status_message.py +++ b/python-restclient/test/test_status_message.py @@ -40,15 +40,14 @@ def make_instance(self, include_optional) -> StatusMessage: job_status = vcell_client.models.simulation_job_status_record.SimulationJobStatusRecord( field_time_data_stamp = '2022-03-10T16:15:50Z', field_vc_sim_id = vcell_client.models.vc_simulation_identifier.VCSimulationIdentifier( - simulation_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + simulation_key = '', owner = vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - name = '', - test_account = True, ), - i_d = '', ), + key = '', + my_specials = [ + 'admins' + ], ), + id = '', ), field_submit_date = '2022-03-10T16:15:50Z', field_scheduler_status = 'WAITING', field_simulation_message = vcell_client.models.simulation_message.SimulationMessage( diff --git a/python-restclient/test/test_user.py b/python-restclient/test/test_user.py index 1dada307ad..0a0af1a83b 100644 --- a/python-restclient/test/test_user.py +++ b/python-restclient/test/test_user.py @@ -38,10 +38,10 @@ def make_instance(self, include_optional) -> User: if include_optional: return User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - name = '', - test_account = True + key = '', + my_specials = [ + 'admins' + ] ) else: return User( diff --git a/python-restclient/test/test_v_cell_software_version.py b/python-restclient/test/test_v_cell_software_version.py index b2a8de89f8..464ca5b8bb 100644 --- a/python-restclient/test/test_v_cell_software_version.py +++ b/python-restclient/test/test_v_cell_software_version.py @@ -45,7 +45,6 @@ def make_instance(self, include_optional) -> VCellSoftwareVersion: minor_version = 56, patch_version = 56, build_int = 56, - site = 'alpha', description = '' ) else: diff --git a/python-restclient/test/test_vc_simulation_identifier.py b/python-restclient/test/test_vc_simulation_identifier.py index 095ebdc859..d9cf05dfe7 100644 --- a/python-restclient/test/test_vc_simulation_identifier.py +++ b/python-restclient/test/test_vc_simulation_identifier.py @@ -37,15 +37,14 @@ def make_instance(self, include_optional) -> VCSimulationIdentifier: model = VCSimulationIdentifier() if include_optional: return VCSimulationIdentifier( - simulation_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), + simulation_key = '', owner = vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - name = '', - test_account = True, ), - i_d = '' + key = '', + my_specials = [ + 'admins' + ], ), + id = '' ) else: return VCSimulationIdentifier( diff --git a/python-restclient/test/test_version.py b/python-restclient/test/test_version.py index 51c6294192..97d53c0d0f 100644 --- a/python-restclient/test/test_version.py +++ b/python-restclient/test/test_version.py @@ -37,31 +37,11 @@ def make_instance(self, include_optional) -> Version: model = Version() if include_optional: return Version( - version_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - version_name = '', - version_owner = vcell_client.models.user.User( - user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), ), - version_group_access = vcell_client.models.group_access.GroupAccess( - groupid = 1.337, - description = '', ), - version_branch_point_ref = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - version_branch_id = 1.337, - version_date = 'Thu Mar 10 00:00:00 UTC 2022', - version_flag = vcell_client.models.version_flag.VersionFlag( - int_value = 56, - archived = True, - current = True, - published = True, ), - version_annot = '', + version_key = '', annot = '', branch_id = 1.337, - branch_point_ref_key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), - var_date = 'Thu Mar 10 00:00:00 UTC 2022', + branch_point_ref_key = '', + var_date = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), flag = vcell_client.models.version_flag.VersionFlag( version_flag = 56, int_value = 56, @@ -74,8 +54,10 @@ def make_instance(self, include_optional) -> Version: name = '', owner = vcell_client.models.user.User( user_name = '', - key = vcell_client.models.key_value.KeyValue( - value = 1.337, ), ) + key = '', + my_specials = [ + 'admins' + ], ) ) else: return Version( diff --git a/python-restclient/vcell_client/__init__.py b/python-restclient/vcell_client/__init__.py index 13c39295c3..5d46548e14 100644 --- a/python-restclient/vcell_client/__init__.py +++ b/python-restclient/vcell_client/__init__.py @@ -83,7 +83,6 @@ from vcell_client.models.simulation_queue_id import SimulationQueueID from vcell_client.models.simulation_status_persistent_record import SimulationStatusPersistentRecord from vcell_client.models.source_model import SourceModel -from vcell_client.models.special_user import SpecialUser from vcell_client.models.status import Status from vcell_client.models.status_message import StatusMessage from vcell_client.models.user import User diff --git a/python-restclient/vcell_client/models/__init__.py b/python-restclient/vcell_client/models/__init__.py index f9b09c4f80..356c571ea7 100644 --- a/python-restclient/vcell_client/models/__init__.py +++ b/python-restclient/vcell_client/models/__init__.py @@ -57,7 +57,6 @@ from vcell_client.models.simulation_queue_id import SimulationQueueID from vcell_client.models.simulation_status_persistent_record import SimulationStatusPersistentRecord from vcell_client.models.source_model import SourceModel -from vcell_client.models.special_user import SpecialUser from vcell_client.models.status import Status from vcell_client.models.status_message import StatusMessage from vcell_client.models.user import User diff --git a/python-restclient/vcell_client/models/special_user.py b/python-restclient/vcell_client/models/special_user.py deleted file mode 100644 index 01caa1172a..0000000000 --- a/python-restclient/vcell_client/models/special_user.py +++ /dev/null @@ -1,99 +0,0 @@ -# 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 StrictStr -from pydantic import Field -from vcell_client.models.specialclaim import SPECIALCLAIM -from vcell_client.models.user import User -try: - from typing import Self -except ImportError: - from typing_extensions import Self - -class SpecialUser(User): - """ - SpecialUser - """ # noqa: E501 - is_special: StrictStr = Field(alias="isSpecial") - my_specials: Optional[List[SPECIALCLAIM]] = Field(default=None, alias="mySpecials") - __properties: ClassVar[List[str]] = ["isSpecial", "userName", "key"] - - 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 SpecialUser 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 SpecialUser 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 SpecialUser) in the input: " + _key) - - _obj = cls.model_validate({ - "isSpecial": obj.get("isSpecial") if obj.get("isSpecial") is not None else 'yes', - "userName": obj.get("userName"), - "key": obj.get("key") - }) - return _obj - - diff --git a/python-restclient/vcell_client/models/user.py b/python-restclient/vcell_client/models/user.py index 726894bebf..933f3a1d84 100644 --- a/python-restclient/vcell_client/models/user.py +++ b/python-restclient/vcell_client/models/user.py @@ -19,9 +19,10 @@ import json -from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Any, ClassVar, Dict, List, Optional from pydantic import BaseModel, StrictStr from pydantic import Field +from vcell_client.models.specialclaim import SPECIALCLAIM try: from typing import Self except ImportError: @@ -31,10 +32,10 @@ class User(BaseModel): """ User """ # noqa: E501 - is_special: StrictStr = Field(alias="isSpecial") user_name: Optional[StrictStr] = Field(default=None, alias="userName") key: Optional[StrictStr] = None - __properties: ClassVar[List[str]] = ["isSpecial", "userName", "key"] + my_specials: Optional[List[SPECIALCLAIM]] = Field(default=None, alias="mySpecials") + __properties: ClassVar[List[str]] = ["userName", "key", "mySpecials"] model_config = { "populate_by_name": True, @@ -42,23 +43,6 @@ class User(BaseModel): } - # JSON field name that stores the object type - __discriminator_property_name: ClassVar[List[str]] = 'isSpecial' - - # discriminator mappings - __discriminator_value_class_map: ClassVar[Dict[str, str]] = { - 'no': 'User','yes': 'SpecialUser' - } - - @classmethod - def get_discriminator_value(cls, obj: Dict) -> str: - """Returns the discriminator value (object type) of the data""" - discriminator_value = obj[cls.__discriminator_property_name] - if discriminator_value: - return cls.__discriminator_value_class_map.get(discriminator_value) - else: - return None - def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -69,7 +53,7 @@ def to_json(self) -> str: return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> Union[Self]: + def from_json(cls, json_str: str) -> Self: """Create an instance of User from a JSON string""" return cls.from_dict(json.loads(json_str)) @@ -92,19 +76,24 @@ def to_dict(self) -> Dict[str, Any]: return _dict @classmethod - def from_dict(cls, obj: Dict) -> Union[Self]: + def from_dict(cls, obj: Dict) -> Self: """Create an instance of User from a dict""" - # look up the object type based on discriminator mapping - object_type = cls.get_discriminator_value(obj) - if object_type: - klass = globals()[object_type] - return klass.from_dict(obj) - else: - raise ValueError("User failed to lookup discriminator value from " + - json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name + - ", mapping: " + json.dumps(cls.__discriminator_value_class_map)) - -from vcell_client.models.special_user import SpecialUser -# TODO: Rewrite to not use raise_errors -User.model_rebuild(raise_errors=False) + 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 User) in the input: " + _key) + + _obj = cls.model_validate({ + "userName": obj.get("userName"), + "key": obj.get("key"), + "mySpecials": obj.get("mySpecials") + }) + return _obj + diff --git a/tools/openapi.yaml b/tools/openapi.yaml index 7ae214ad78..fa414dc2a3 100644 --- a/tools/openapi.yaml +++ b/tools/openapi.yaml @@ -2529,20 +2529,6 @@ components: type: string modelType: $ref: '#/components/schemas/ModelType' - SpecialUser: - required: - - isSpecial - type: object - allOf: - - $ref: '#/components/schemas/User' - properties: - isSpecial: - default: "yes" - type: string - mySpecials: - type: array - items: - $ref: '#/components/schemas/SPECIAL_CLAIM' Status: enum: - UNKNOWN @@ -2572,22 +2558,16 @@ components: format: double type: number User: - required: - - isSpecial type: object properties: - isSpecial: - default: "no" - type: string userName: type: string key: $ref: '#/components/schemas/KeyValue' - discriminator: - propertyName: isSpecial - mapping: - "no": '#/components/schemas/User' - "yes": '#/components/schemas/SpecialUser' + mySpecials: + type: array + items: + $ref: '#/components/schemas/SPECIAL_CLAIM' UserIdentityJSONSafe: type: object properties: diff --git a/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java b/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java index ec4250ffcc..8b7b4f4fac 100644 --- a/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java +++ b/vcell-core/src/main/java/org/vcell/util/document/SpecialUser.java @@ -12,14 +12,12 @@ import java.util.Arrays; -@Schema(allOf = {User.class}, requiredProperties = {"isSpecial"}, properties = {@SchemaProperty(name = "isSpecial", defaultValue = "yes", type = SchemaType.STRING)}) +@Schema(implementation = User.class) public class SpecialUser extends User implements Serializable, Matchable, Immutable { private final static String PREVIOUS_DATABASE_VALUE_ADMIN = "special0"; private final static String PREVIOUS_DATABASE_VALUE_POWERUSER = "special1"; private final static String PREVIOUS_DATABASE_VALUE_PUBLICATION = "publication"; - public final String isSpecial = "yes"; - public enum SPECIAL_CLAIM { admins/*special0*/, powerUsers/*special1*/, @@ -44,8 +42,6 @@ public String toDatabaseString(){ } };//Must match a name 'special' column of 'vc_specialusers'// table - protected SPECIAL_CLAIM[] mySpecials; - public SpecialUser(String userid, KeyValue key, SPECIAL_CLAIM[] mySpecials) { super(userid, key); this.mySpecials = mySpecials; diff --git a/vcell-core/src/main/java/org/vcell/util/document/User.java b/vcell-core/src/main/java/org/vcell/util/document/User.java index e6a91abe49..2392553d05 100644 --- a/vcell-core/src/main/java/org/vcell/util/document/User.java +++ b/vcell-core/src/main/java/org/vcell/util/document/User.java @@ -26,22 +26,13 @@ * This type was created in VisualAge. */ @SuppressWarnings("serial") -@Schema( - discriminatorProperty = "isSpecial", - discriminatorMapping = { - @DiscriminatorMapping(value = "no", schema = User.class), - @DiscriminatorMapping(value = "yes", schema = SpecialUser.class) - }, - requiredProperties = {"isSpecial"}, - properties = {@SchemaProperty(name = "isSpecial", defaultValue = "no", type = SchemaType.STRING)} -) public class User implements java.io.Serializable, Matchable, Immutable { @JsonProperty private String userName = null; @JsonProperty private KeyValue key = null; - public final String isSpecial = "no"; + protected SpecialUser.SPECIAL_CLAIM[] mySpecials; public static final String VCellTestAccountName = "vcelltestaccount"; public static final User tempUser = new User("temp",new KeyValue("123")); diff --git a/vcell-restclient/.openapi-generator/FILES b/vcell-restclient/.openapi-generator/FILES index 3e22961fd5..a496fdb3fc 100644 --- a/vcell-restclient/.openapi-generator/FILES +++ b/vcell-restclient/.openapi-generator/FILES @@ -52,7 +52,6 @@ docs/SimulationResourceApi.md docs/SimulationStatusPersistentRecord.md docs/SolverResourceApi.md docs/SourceModel.md -docs/SpecialUser.md docs/Status.md docs/StatusMessage.md docs/User.md @@ -132,7 +131,6 @@ src/main/java/org/vcell/restclient/model/SimulationQueueEntryStatusRecord.java src/main/java/org/vcell/restclient/model/SimulationQueueID.java src/main/java/org/vcell/restclient/model/SimulationStatusPersistentRecord.java src/main/java/org/vcell/restclient/model/SourceModel.java -src/main/java/org/vcell/restclient/model/SpecialUser.java src/main/java/org/vcell/restclient/model/Status.java src/main/java/org/vcell/restclient/model/StatusMessage.java src/main/java/org/vcell/restclient/model/User.java diff --git a/vcell-restclient/README.md b/vcell-restclient/README.md index 59c117b1a1..c9f7a87656 100644 --- a/vcell-restclient/README.md +++ b/vcell-restclient/README.md @@ -245,7 +245,6 @@ Class | Method | HTTP request | Description - [SimulationQueueID](docs/SimulationQueueID.md) - [SimulationStatusPersistentRecord](docs/SimulationStatusPersistentRecord.md) - [SourceModel](docs/SourceModel.md) - - [SpecialUser](docs/SpecialUser.md) - [Status](docs/Status.md) - [StatusMessage](docs/StatusMessage.md) - [User](docs/User.md) diff --git a/vcell-restclient/api/openapi.yaml b/vcell-restclient/api/openapi.yaml index 9a143ef422..5aaa2d9372 100644 --- a/vcell-restclient/api/openapi.yaml +++ b/vcell-restclient/api/openapi.yaml @@ -2137,7 +2137,9 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key url: url @@ -2154,7 +2156,9 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key url: url @@ -2167,7 +2171,9 @@ components: version: date: 2000-01-23T04:56:07.000+00:00 owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key branchID: 0.8008281904610115 @@ -2352,7 +2358,9 @@ components: ExternalDataIdentifier: example: owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key dataKey: dataKey @@ -2461,7 +2469,9 @@ components: annotation: annotation fieldDataID: owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key dataKey: dataKey @@ -2577,7 +2587,9 @@ components: version: date: 2000-01-23T04:56:07.000+00:00 owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key branchID: 0.8008281904610115 @@ -2807,7 +2819,9 @@ components: version: date: 2000-01-23T04:56:07.000+00:00 owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key branchID: 0.8008281904610115 @@ -2842,7 +2856,9 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key url: url @@ -2859,7 +2875,9 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key url: url @@ -3028,7 +3046,9 @@ components: publicationKey: publicationKey pubmedid: pubmedid user: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key url: url @@ -3141,7 +3161,9 @@ components: jobNumber: 0 fieldVCSimID: owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key simulationKey: simulationKey @@ -3246,25 +3268,6 @@ components: modelType: $ref: '#/components/schemas/ModelType' type: object - SpecialUser: - properties: - userName: - type: string - key: - type: string - specialUser: - type: string - mySpecials: - items: - $ref: '#/components/schemas/SPECIAL_CLAIM' - type: array - admin: - type: boolean - publisher: - type: boolean - vCellSupport: - type: boolean - type: object Status: enum: - UNKNOWN @@ -3305,7 +3308,9 @@ components: jobNumber: 0 fieldVCSimID: owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key simulationKey: simulationKey @@ -3334,13 +3339,10 @@ components: type: number type: object User: - discriminator: - mapping: - "no": '#/components/schemas/User' - "yes": '#/components/schemas/SpecialUser' - propertyName: specialUser example: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key properties: @@ -3348,8 +3350,10 @@ components: type: string key: type: string - specialUser: - type: string + mySpecials: + items: + $ref: '#/components/schemas/SPECIAL_CLAIM' + type: array type: object UserIdentityJSONSafe: example: @@ -3409,7 +3413,9 @@ components: VCSimulationIdentifier: example: owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key simulationKey: simulationKey @@ -3518,7 +3524,9 @@ components: example: date: 2000-01-23T04:56:07.000+00:00 owner: - specialUser: specialUser + mySpecials: + - null + - null userName: userName key: key branchID: 0.8008281904610115 diff --git a/vcell-restclient/docs/User.md b/vcell-restclient/docs/User.md index f955812d0e..49943e227e 100644 --- a/vcell-restclient/docs/User.md +++ b/vcell-restclient/docs/User.md @@ -7,9 +7,9 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| -|**isSpecial** | **String** | | | |**userName** | **String** | | [optional] | |**key** | **String** | | [optional] | +|**mySpecials** | **List<SPECIALCLAIM>** | | [optional] | diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/api/FieldDataResourceApi.java b/vcell-restclient/src/main/java/org/vcell/restclient/api/FieldDataResourceApi.java index d4137383a2..6845782736 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/api/FieldDataResourceApi.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/api/FieldDataResourceApi.java @@ -12,7 +12,6 @@ package org.vcell.restclient.api; -import com.fasterxml.jackson.core.JsonProcessingException; import org.vcell.restclient.ApiClient; import org.vcell.restclient.ApiException; import org.vcell.restclient.ApiResponse; @@ -100,7 +99,7 @@ private String formatExceptionMessage(String operationId, int statusCode, String /** * Create Field Data with granular detail in one request.The following files are accepted: .tif and .zip. - * + * * @param _file (optional) * @param fileName (optional) * @param extent (optional) @@ -119,7 +118,7 @@ public FieldDataSavedResults advancedCreate(File _file, String fileName, Extent /** * Create Field Data with granular detail in one request.The following files are accepted: .tif and .zip. - * + * * @param _file (optional) * @param fileName (optional) * @param extent (optional) @@ -175,13 +174,8 @@ private HttpRequest.Builder advancedCreateRequestBuilder(File _file, String file multiPartBuilder.addBinaryBody("file", _file); hasFiles = true; multiPartBuilder.addTextBody("fileName", fileName.toString()); - try { - multiPartBuilder.addTextBody("extent", memberVarObjectMapper.writeValueAsString(extent)); - multiPartBuilder.addTextBody("iSize", memberVarObjectMapper.writeValueAsString(iSize)); - multiPartBuilder.addTextBody("origin", memberVarObjectMapper.writeValueAsString(origin)); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + multiPartBuilder.addTextBody("extent", extent.toString()); + multiPartBuilder.addTextBody("iSize", iSize.toString()); for (int i=0; i < channelNames.size(); i++) { multiPartBuilder.addTextBody("channelNames", channelNames.get(i).toString()); } @@ -189,6 +183,7 @@ private HttpRequest.Builder advancedCreateRequestBuilder(File _file, String file multiPartBuilder.addTextBody("times", times.get(i).toString()); } multiPartBuilder.addTextBody("annotation", annotation.toString()); + multiPartBuilder.addTextBody("origin", origin.toString()); HttpEntity entity = multiPartBuilder.build(); HttpRequest.BodyPublisher formDataPublisher; if (hasFiles) { diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/SpecialUser.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/SpecialUser.java deleted file mode 100644 index 9f228c9464..0000000000 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/SpecialUser.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * 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.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -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.SPECIALCLAIM; -import org.vcell.restclient.model.User; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - - -import org.vcell.restclient.JSON; -/** - * SpecialUser - */ -@JsonPropertyOrder({ - SpecialUser.JSON_PROPERTY_IS_SPECIAL, - SpecialUser.JSON_PROPERTY_MY_SPECIALS -}) -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -@JsonIgnoreProperties( - value = "isSpecial", // ignore manually set isSpecial, it will be automatically generated by Jackson during serialization - allowSetters = true // allows the isSpecial to be set during deserialization -) -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "isSpecial", visible = true) - -public class SpecialUser extends User { - public static final String JSON_PROPERTY_IS_SPECIAL = "isSpecial"; - private String isSpecial = "yes"; - - public static final String JSON_PROPERTY_MY_SPECIALS = "mySpecials"; - private List mySpecials; - - public SpecialUser() { - } - - public SpecialUser isSpecial(String isSpecial) { - this.isSpecial = isSpecial; - return this; - } - - /** - * Get isSpecial - * @return isSpecial - **/ - @javax.annotation.Nonnull - @JsonProperty(JSON_PROPERTY_IS_SPECIAL) - @JsonInclude(value = JsonInclude.Include.ALWAYS) - - public String getIsSpecial() { - return isSpecial; - } - - - @JsonProperty(JSON_PROPERTY_IS_SPECIAL) - @JsonInclude(value = JsonInclude.Include.ALWAYS) - public void setIsSpecial(String isSpecial) { - this.isSpecial = isSpecial; - } - - - public SpecialUser mySpecials(List mySpecials) { - this.mySpecials = mySpecials; - return this; - } - - public SpecialUser addMySpecialsItem(SPECIALCLAIM mySpecialsItem) { - if (this.mySpecials == null) { - this.mySpecials = new ArrayList<>(); - } - this.mySpecials.add(mySpecialsItem); - return this; - } - - /** - * Get mySpecials - * @return mySpecials - **/ - @javax.annotation.Nullable - @JsonProperty(JSON_PROPERTY_MY_SPECIALS) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public List getMySpecials() { - return mySpecials; - } - - - @JsonProperty(JSON_PROPERTY_MY_SPECIALS) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setMySpecials(List mySpecials) { - this.mySpecials = mySpecials; - } - - - @Override - public SpecialUser userName(String userName) { - this.setUserName(userName); - return this; - } - - @Override - public SpecialUser key(String key) { - this.setKey(key); - return this; - } - - /** - * Return true if this SpecialUser object is equal to o. - */ - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SpecialUser specialUser = (SpecialUser) o; - return Objects.equals(this.isSpecial, specialUser.isSpecial) && - Objects.equals(this.mySpecials, specialUser.mySpecials) && - super.equals(o); - } - - @Override - public int hashCode() { - return Objects.hash(isSpecial, mySpecials, super.hashCode()); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class SpecialUser {\n"); - sb.append(" ").append(toIndentedString(super.toString())).append("\n"); - sb.append(" isSpecial: ").append(toIndentedString(isSpecial)).append("\n"); - sb.append(" mySpecials: ").append(toIndentedString(mySpecials)).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 `isSpecial` to the URL query string - if (getIsSpecial() != null) { - joiner.add(String.format("%sisSpecial%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getIsSpecial()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - - // add `userName` to the URL query string - if (getUserName() != null) { - joiner.add(String.format("%suserName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getUserName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - - // add `key` to the URL query string - if (getKey() != null) { - joiner.add(String.format("%skey%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getKey()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - - return joiner.toString(); - } -static { - // Initialize and register the discriminator mappings. - Map> mappings = new HashMap>(); - mappings.put("SpecialUser", SpecialUser.class); - JSON.registerDiscriminator(SpecialUser.class, "isSpecial", mappings); -} -} - diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/User.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/User.java index 43912351c9..e4d771daa9 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/User.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/User.java @@ -19,76 +19,40 @@ import java.util.Objects; import java.util.Map; import java.util.HashMap; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; 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.SPECIALCLAIM; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import org.vcell.restclient.JSON; /** * User */ @JsonPropertyOrder({ - User.JSON_PROPERTY_IS_SPECIAL, User.JSON_PROPERTY_USER_NAME, - User.JSON_PROPERTY_KEY + User.JSON_PROPERTY_KEY, + User.JSON_PROPERTY_MY_SPECIALS }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -@JsonIgnoreProperties( - value = "isSpecial", // ignore manually set isSpecial, it will be automatically generated by Jackson during serialization - allowSetters = true // allows the isSpecial to be set during deserialization -) -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "isSpecial", visible = true) -@JsonSubTypes({ - @JsonSubTypes.Type(value = User.class, name = "no"), - @JsonSubTypes.Type(value = SpecialUser.class, name = "yes"), -}) - public class User { - public static final String JSON_PROPERTY_IS_SPECIAL = "isSpecial"; - private String isSpecial = "no"; - public static final String JSON_PROPERTY_USER_NAME = "userName"; private String userName; public static final String JSON_PROPERTY_KEY = "key"; private String key; - public User() { - } - - public User isSpecial(String isSpecial) { - this.isSpecial = isSpecial; - return this; - } - - /** - * Get isSpecial - * @return isSpecial - **/ - @javax.annotation.Nonnull - @JsonProperty(JSON_PROPERTY_IS_SPECIAL) - @JsonInclude(value = JsonInclude.Include.ALWAYS) - - public String getIsSpecial() { - return isSpecial; - } + public static final String JSON_PROPERTY_MY_SPECIALS = "mySpecials"; + private List mySpecials; - - @JsonProperty(JSON_PROPERTY_IS_SPECIAL) - @JsonInclude(value = JsonInclude.Include.ALWAYS) - public void setIsSpecial(String isSpecial) { - this.isSpecial = isSpecial; + public User() { } - public User userName(String userName) { this.userName = userName; return this; @@ -139,6 +103,39 @@ public void setKey(String key) { } + public User mySpecials(List mySpecials) { + this.mySpecials = mySpecials; + return this; + } + + public User addMySpecialsItem(SPECIALCLAIM mySpecialsItem) { + if (this.mySpecials == null) { + this.mySpecials = new ArrayList<>(); + } + this.mySpecials.add(mySpecialsItem); + return this; + } + + /** + * Get mySpecials + * @return mySpecials + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_MY_SPECIALS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getMySpecials() { + return mySpecials; + } + + + @JsonProperty(JSON_PROPERTY_MY_SPECIALS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMySpecials(List mySpecials) { + this.mySpecials = mySpecials; + } + + /** * Return true if this User object is equal to o. */ @@ -151,23 +148,23 @@ public boolean equals(Object o) { return false; } User user = (User) o; - return Objects.equals(this.isSpecial, user.isSpecial) && - Objects.equals(this.userName, user.userName) && - Objects.equals(this.key, user.key); + return Objects.equals(this.userName, user.userName) && + Objects.equals(this.key, user.key) && + Objects.equals(this.mySpecials, user.mySpecials); } @Override public int hashCode() { - return Objects.hash(isSpecial, userName, key); + return Objects.hash(userName, key, mySpecials); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class User {\n"); - sb.append(" isSpecial: ").append(toIndentedString(isSpecial)).append("\n"); sb.append(" userName: ").append(toIndentedString(userName)).append("\n"); sb.append(" key: ").append(toIndentedString(key)).append("\n"); + sb.append(" mySpecials: ").append(toIndentedString(mySpecials)).append("\n"); sb.append("}"); return sb.toString(); } @@ -215,11 +212,6 @@ public String toUrlQueryString(String prefix) { StringJoiner joiner = new StringJoiner("&"); - // add `isSpecial` to the URL query string - if (getIsSpecial() != null) { - joiner.add(String.format("%sisSpecial%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getIsSpecial()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); - } - // add `userName` to the URL query string if (getUserName() != null) { joiner.add(String.format("%suserName%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getUserName()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); @@ -230,15 +222,18 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format("%skey%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getKey()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } + // add `mySpecials` to the URL query string + if (getMySpecials() != null) { + for (int i = 0; i < getMySpecials().size(); i++) { + if (getMySpecials().get(i) != null) { + joiner.add(String.format("%smySpecials%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix), + URLEncoder.encode(String.valueOf(getMySpecials().get(i)), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + } + } + return joiner.toString(); } -static { - // Initialize and register the discriminator mappings. - Map> mappings = new HashMap>(); - mappings.put("no", User.class); - mappings.put("yes", SpecialUser.class); - mappings.put("User", User.class); - JSON.registerDiscriminator(User.class, "isSpecial", mappings); -} } diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/utils/DtoModelTransforms.java b/vcell-restclient/src/main/java/org/vcell/restclient/utils/DtoModelTransforms.java index b88025e4cc..f8a8abba38 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/utils/DtoModelTransforms.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/utils/DtoModelTransforms.java @@ -8,25 +8,22 @@ import cbit.vcell.math.VariableType; import cbit.vcell.simdata.DataIdentifier; import org.vcell.restclient.model.*; -import org.vcell.restclient.model.SpecialUser; import org.vcell.util.Extent; import org.vcell.util.Origin; -import org.vcell.util.document.*; import org.vcell.util.document.BioModelChildSummary; import org.vcell.util.document.ExternalDataIdentifier; import org.vcell.util.document.GroupAccess; import org.vcell.util.document.GroupAccessAll; import org.vcell.util.document.GroupAccessNone; import org.vcell.util.document.GroupAccessSome; -import org.vcell.util.document.KeyValue; import org.vcell.util.document.MathModelChildSummary; import org.vcell.util.document.PublicationInfo; import org.vcell.util.document.User; import org.vcell.util.document.VCellSoftwareVersion; import org.vcell.util.document.Version; import org.vcell.util.document.VersionFlag; +import org.vcell.util.document.*; -import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @@ -114,14 +111,11 @@ public static org.vcell.restclient.model.User userToDTO(User user) { } public static User dtoToUser(org.vcell.restclient.model.User dto){ - if (dto instanceof SpecialUser sp && sp.getMySpecials() != null) { - org.vcell.util.document.SpecialUser.SpecialUserBuilder builder = new org.vcell.util.document.SpecialUser.SpecialUserBuilder(dto.getUserName(), new KeyValue(dto.getKey())); - for (SPECIALCLAIM claim : sp.getMySpecials()){ - builder.addSpecial(org.vcell.util.document.SpecialUser.SPECIAL_CLAIM.valueOf(claim.getValue())); - } - return builder.build(); + SpecialUser.SPECIAL_CLAIM[] claims = new SpecialUser.SPECIAL_CLAIM[] {}; + if (dto.getMySpecials() != null) { + claims = dto.getMySpecials().stream().map(c -> SpecialUser.SPECIAL_CLAIM.fromDatabase(c.getValue())).toArray(SpecialUser.SPECIAL_CLAIM[]::new); } - return new User(dto.getUserName(), new KeyValue(dto.getKey())); + return new SpecialUser(dto.getUserName(), new KeyValue(dto.getKey()), claims); } public static cbit.vcell.field.io.FieldDataShape DTOToFieldDataShape(FieldDataShape dto){ diff --git a/vcell-restclient/src/test/java/org/vcell/restclient/model/SpecialUserTest.java b/vcell-restclient/src/test/java/org/vcell/restclient/model/SpecialUserTest.java deleted file mode 100644 index 1ff3cf16a4..0000000000 --- a/vcell-restclient/src/test/java/org/vcell/restclient/model/SpecialUserTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.SPECIALCLAIM; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; - -/** - * Model tests for SpecialUser - */ -public class SpecialUserTest { - private final SpecialUser model = new SpecialUser(); - - /** - * Model tests for SpecialUser - */ - @Test - public void testSpecialUser() { - // TODO: test SpecialUser - } - - /** - * Test the property 'userName' - */ - @Test - public void userNameTest() { - // TODO: test userName - } - - /** - * Test the property 'key' - */ - @Test - public void keyTest() { - // TODO: test key - } - - /** - * Test the property 'mySpecials' - */ - @Test - public void mySpecialsTest() { - // TODO: test mySpecials - } - - /** - * Test the property 'admin' - */ - @Test - public void adminTest() { - // TODO: test admin - } - - /** - * Test the property 'publisher' - */ - @Test - public void publisherTest() { - // TODO: test publisher - } - - /** - * Test the property 'vCellSupport' - */ - @Test - public void vCellSupportTest() { - // TODO: test vCellSupport - } - -} 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 65345d9daf..cddd3007d3 100644 --- a/webapp-ng/src/app/core/modules/openapi/.openapi-generator/FILES +++ b/webapp-ng/src/app/core/modules/openapi/.openapi-generator/FILES @@ -68,7 +68,6 @@ model/simulation-queue-entry-status-record.ts model/simulation-queue-id.ts model/simulation-status-persistent-record.ts model/source-model.ts -model/special-user.ts model/specialclaim.ts model/status-message.ts model/status.ts 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 55adac9310..6859453389 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/models.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/models.ts @@ -40,7 +40,6 @@ export * from './simulation-queue-entry-status-record'; export * from './simulation-queue-id'; export * from './simulation-status-persistent-record'; export * from './source-model'; -export * from './special-user'; export * from './status'; export * from './status-message'; export * from './user'; diff --git a/webapp-ng/src/app/core/modules/openapi/model/special-user.ts b/webapp-ng/src/app/core/modules/openapi/model/special-user.ts deleted file mode 100644 index 8c36be5dde..0000000000 --- a/webapp-ng/src/app/core/modules/openapi/model/special-user.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * 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 { SPECIALCLAIM } from './specialclaim'; -import { User } from './user'; - - -export interface SpecialUser extends User { - isSpecial: string; - mySpecials?: Array; -} - diff --git a/webapp-ng/src/app/core/modules/openapi/model/user.ts b/webapp-ng/src/app/core/modules/openapi/model/user.ts index 5d712aa4ea..f831586065 100644 --- a/webapp-ng/src/app/core/modules/openapi/model/user.ts +++ b/webapp-ng/src/app/core/modules/openapi/model/user.ts @@ -9,11 +9,12 @@ * https://openapi-generator.tech * Do not edit the class manually. */ +import { SPECIALCLAIM } from './specialclaim'; export interface User { - isSpecial: string; userName?: string; key?: string; + mySpecials?: Array; } From df71bca8d6f27f791e4a78be001fed9452185791 Mon Sep 17 00:00:00 2001 From: Ezequiel Valencia Date: Thu, 19 Jun 2025 10:57:10 -0400 Subject: [PATCH 13/13] Apply Field Data Patch --- python-restclient/.openapi-generator/FILES | 67 ------------------- tools/generate.sh | 16 ++--- .../restclient/api/FieldDataResourceApi.java | 15 +++-- 3 files changed, 18 insertions(+), 80 deletions(-) diff --git a/python-restclient/.openapi-generator/FILES b/python-restclient/.openapi-generator/FILES index 60e115c1aa..497822986b 100644 --- a/python-restclient/.openapi-generator/FILES +++ b/python-restclient/.openapi-generator/FILES @@ -69,73 +69,6 @@ docs/VariableType.md docs/Version.md docs/VersionFlag.md test/__init__.py -test/test_acces_token_representation_record.py -test/test_admin_resource_api.py -test/test_application_info.py -test/test_batch_system_type.py -test/test_bio_model.py -test/test_bio_model_child_summary.py -test/test_bio_model_resource_api.py -test/test_bio_model_summary.py -test/test_biomodel_ref.py -test/test_data_identifier.py -test/test_detailed_state.py -test/test_domain.py -test/test_extent.py -test/test_external_data_identifier.py -test/test_field_data.py -test/test_field_data_reference.py -test/test_field_data_resource_api.py -test/test_field_data_saved_results.py -test/test_field_data_shape.py -test/test_geometry_resource_api.py -test/test_geometry_summary.py -test/test_group_access.py -test/test_group_access_all.py -test/test_group_access_none.py -test/test_group_access_some.py -test/test_hello_world_api.py -test/test_hello_world_message.py -test/test_htc_job_id.py -test/test_i_size.py -test/test_identity.py -test/test_math_model_child_summary.py -test/test_math_model_resource_api.py -test/test_math_model_summary.py -test/test_math_type.py -test/test_mathmodel_ref.py -test/test_model_type.py -test/test_origin.py -test/test_publication.py -test/test_publication_info.py -test/test_publication_resource_api.py -test/test_scheduler_status.py -test/test_simulation_execution_status_record.py -test/test_simulation_job_status_record.py -test/test_simulation_message.py -test/test_simulation_queue_entry_status_record.py -test/test_simulation_queue_id.py -test/test_simulation_resource_api.py -test/test_simulation_status_persistent_record.py -test/test_solver_resource_api.py -test/test_source_model.py -test/test_specialclaim.py -test/test_status.py -test/test_status_message.py -test/test_user.py -test/test_user_identity_json_safe.py -test/test_user_login_info_for_mapping.py -test/test_user_registration_info.py -test/test_users_resource_api.py -test/test_v_cell_http_error.py -test/test_v_cell_site.py -test/test_v_cell_software_version.py -test/test_variable_domain.py -test/test_variable_type.py -test/test_vc_document_type.py -test/test_vc_simulation_identifier.py -test/test_version.py -test/test_version_flag.py tox.ini vcell_client/__init__.py vcell_client/api/__init__.py diff --git a/tools/generate.sh b/tools/generate.sh index 8a2b8e4b3f..a7b1b12763 100755 --- a/tools/generate.sh +++ b/tools/generate.sh @@ -22,14 +22,14 @@ docker run --rm -v ${parentDir}:/vcell \ -o /vcell/vcell-restclient \ -c /vcell/tools/java-config.yaml -## Apply the patch to AdminResourceApi.java to treat getUsage() as a PDF file rather than a JSON file -#pushd "${parentDir}" || { echo "Failed to change directory to ${parentDir}"; exit 1; } -#if ! git apply "${scriptDir}/FieldDataResourceApi.patch"; then -# echo "Failed to apply FieldDataResourceApi.patch" -# exit 1 -#fi -#popd || { echo "Failed to return to the previous directory"; exit 1; } -# +# Apply the patch to AdminResourceApi.java to treat getUsage() as a PDF file rather than a JSON file +pushd "${parentDir}" || { echo "Failed to change directory to ${parentDir}"; exit 1; } +if ! git apply "${scriptDir}/FieldDataResourceApi.patch"; then + echo "Failed to apply FieldDataResourceApi.patch" + exit 1 +fi +popd || { echo "Failed to return to the previous directory"; exit 1; } + docker run --rm -v ${parentDir}:/vcell \ ${generatorCliImage} generate \ diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/api/FieldDataResourceApi.java b/vcell-restclient/src/main/java/org/vcell/restclient/api/FieldDataResourceApi.java index 6845782736..d4137383a2 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/api/FieldDataResourceApi.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/api/FieldDataResourceApi.java @@ -12,6 +12,7 @@ package org.vcell.restclient.api; +import com.fasterxml.jackson.core.JsonProcessingException; import org.vcell.restclient.ApiClient; import org.vcell.restclient.ApiException; import org.vcell.restclient.ApiResponse; @@ -99,7 +100,7 @@ private String formatExceptionMessage(String operationId, int statusCode, String /** * Create Field Data with granular detail in one request.The following files are accepted: .tif and .zip. - * + * * @param _file (optional) * @param fileName (optional) * @param extent (optional) @@ -118,7 +119,7 @@ public FieldDataSavedResults advancedCreate(File _file, String fileName, Extent /** * Create Field Data with granular detail in one request.The following files are accepted: .tif and .zip. - * + * * @param _file (optional) * @param fileName (optional) * @param extent (optional) @@ -174,8 +175,13 @@ private HttpRequest.Builder advancedCreateRequestBuilder(File _file, String file multiPartBuilder.addBinaryBody("file", _file); hasFiles = true; multiPartBuilder.addTextBody("fileName", fileName.toString()); - multiPartBuilder.addTextBody("extent", extent.toString()); - multiPartBuilder.addTextBody("iSize", iSize.toString()); + try { + multiPartBuilder.addTextBody("extent", memberVarObjectMapper.writeValueAsString(extent)); + multiPartBuilder.addTextBody("iSize", memberVarObjectMapper.writeValueAsString(iSize)); + multiPartBuilder.addTextBody("origin", memberVarObjectMapper.writeValueAsString(origin)); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } for (int i=0; i < channelNames.size(); i++) { multiPartBuilder.addTextBody("channelNames", channelNames.get(i).toString()); } @@ -183,7 +189,6 @@ private HttpRequest.Builder advancedCreateRequestBuilder(File _file, String file multiPartBuilder.addTextBody("times", times.get(i).toString()); } multiPartBuilder.addTextBody("annotation", annotation.toString()); - multiPartBuilder.addTextBody("origin", origin.toString()); HttpEntity entity = multiPartBuilder.build(); HttpRequest.BodyPublisher formDataPublisher; if (hasFiles) {