Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b42ec2f
add delegating data source - initial commit
adamkorynta Nov 18, 2025
ae88c84
parameterize orgainzation (office) id from the client to the REST API
adamkorynta Nov 24, 2025
9bb3262
allow the client to choose an organization id in the login prompt
adamkorynta Nov 26, 2025
5dc5b76
add organization selector to allow clients to change organizations wi…
adamkorynta Dec 4, 2025
99a74c5
cleanup order of operations so that excessive invalid requests aren't…
adamkorynta Dec 4, 2025
df151d6
revert changes
adamkorynta Dec 4, 2025
5398667
cache changes to platform ref in attempt to speedup performance
adamkorynta Dec 4, 2025
cd2f472
Update opendcs-web-client/src/main/webapp/WEB-INF/common/header.jspf
adamkorynta Dec 4, 2025
e2d460d
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
adamkorynta Dec 4, 2025
0c0060d
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
adamkorynta Dec 5, 2025
021c60b
more updates from review
adamkorynta Dec 5, 2025
057eebd
fix jstl references for jakarta update
adamkorynta Dec 5, 2025
5eb1b27
Merge remote-tracking branch 'origin/main' into feature/client_office_id
adamkorynta Dec 8, 2025
b7dabb8
code review updates
adamkorynta Dec 8, 2025
72b4932
more updates from feedback
adamkorynta Dec 9, 2025
9b2b397
update status text
adamkorynta Dec 9, 2025
a468031
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
adamkorynta Dec 9, 2025
86ecaf8
remove loginTest as it isn't hooked into integration test system
adamkorynta Dec 9, 2025
f374f1b
update organizations to include extra metadata
adamkorynta Dec 9, 2025
001b5bd
cleanup for defaulting to HQ organization
adamkorynta Dec 9, 2025
271a701
refactor session office prepare to cwms
adamkorynta Dec 9, 2025
0d19ab4
cleanup opentsdb tests
adamkorynta Dec 9, 2025
7af924a
cleanup organization openapi test
adamkorynta Dec 9, 2025
df85b6d
fixing CWMS tests
adamkorynta Dec 9, 2025
ca1e752
add org header to swagger page
adamkorynta Dec 9, 2025
c91eb89
fix typo
adamkorynta Dec 10, 2025
d9d0404
Update opendcs-rest-api/src/main/java/org/opendcs/odcsapi/dao/cwms/Cw…
adamkorynta Dec 10, 2025
9c57a9b
sonar updates
adamkorynta Dec 10, 2025
374fb48
fix typo
adamkorynta Dec 10, 2025
6e332bc
cleanup css form and replace some `window` with `globalThis`
adamkorynta Dec 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ docker run --network database_net \
-e DB_URL=jdbc:postgres:db:5324/dcs \
-e DB_USERNAME=dcs_app \
-e DB_PASSWORD=dcs_app_password \
-e DB_CONNECTION_INIT="select 1" \
-e DB_VALIDATION_QUERY="select 1" \
-e DB_MAX_CONNECTIONS=10 \
-e DB_MAX_IDLE=5 \
Expand All @@ -128,7 +127,6 @@ docker run --network database_net \
-e DB_URL=jdbc:oracle:thin:@//cwmsdb:1521/CWMSTEST \
-e DB_USERNAME=ccp_app \
-e DB_PASSWORD=ccp \
-e DB_CONNECTION_INIT="BEGIN cwms_ccp_vpd.set_ccp_session_ctx(null, null, 'SPK' ); END;" \
-e DB_VALIDATION_QUERY="select 1 from dual" \
-e DB_MAX_CONNECTIONS=10 \
-e DB_MAX_IDLE=5 \
Expand Down
1 change: 0 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ services:
- DB_DRIVER_CLASS=org.postgresql.Driver
- DB_USERNAME=app
- DB_PASSWORD=app_pass
- DB_CONNECTION_INIT=SELECT 1
- DB_VALIDATION_QUERY=SELECT 1
- DB_URL=jdbc:postgresql://db:5432/dcs
- DB_MAX_CONNECTIONS=10
Expand Down
1 change: 0 additions & 1 deletion docker_files/tomcat/conf/context.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
username="${DB_USERNAME}"
password="${DB_PASSWORD}"
driverClassName="${DB_DRIVER_CLASS}"
initSQL="${DB_CONNECTION_INIT}"
logAbandoned="true"
url="${DB_URL}"
logValidationErrors="true"
Expand Down
1 change: 0 additions & 1 deletion gradle.properties.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#DCSTOOL_USERDIR=

###Point to existing Postgres OpenTS database
#postgresdb.url=
#opendcs.db.username=
#opendcs.db.password=

Expand Down
6 changes: 4 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
opendcs = "7.5.1-RC17"
opendcs = "7.5.1-RC18"

servlet-api = "6.1.0" #Updating this further will require a change to the jakarta namespace.
servlet-api = "6.1.0"
slf4j = { strictly = "2.0.17" }
jersey = "4.0.0"

Expand Down Expand Up @@ -40,6 +40,8 @@ opendcs-api = { module = "org.opendcs:opendcs-api", version.ref = "opendcs" }
opendcs-schemas = { module = "org.opendcs:opendcs-schemas", version.ref = "opendcs" }
opendcs-schemas-cwms = { module = "org.opendcs:opendcs-schemas-cwms-oracle", version.ref = "opendcs" }

jdbi = { module = "org.jdbi:jdbi3-core", version = "3.39.1" }

servlet-api = { module = "jakarta.servlet:jakarta.servlet-api", version.ref = "servlet-api" }
rs-api = { module = "jakarta.ws.rs:jakarta.ws.rs-api", version.ref="rs-api" }
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@
public final class TomcatServer implements AutoCloseable
{
private static final Logger log = OpenDcsLoggerFactory.getLogger();
public static final String DB_OFFICE = "DB_OFFICE";
public static final String DB_DRIVER_CLASS = "DB_DRIVER_CLASS";
public static final String DB_DATASOURCE_CLASS = "DB_DATASOURCE_CLASS";
public static final String DB_CONNECTION_INIT = "DB_CONNECTION_INIT";
public static final String DB_VALIDATION_QUERY = "DB_VALIDATION_QUERY";
public static final String DB_URL = "DB_URL";
public static final String DB_USERNAME = "DB_USERNAME";
Expand Down Expand Up @@ -196,10 +194,6 @@ private static void setupDbForBypass(DbType dbType)
{
System.setProperty(DB_DRIVER_CLASS, "oracle.jdbc.driver.OracleDriver");
System.setProperty(DB_DATASOURCE_CLASS, DataSourceFactory.class.getName());
String dbOffice = System.getProperty("testcontainer.cwms.bypass.office.id");
String initScript = String.format("BEGIN cwms_ccp_vpd.set_ccp_session_ctx(cwms_util.get_office_code('%s'), 2, '%s' ); END;", dbOffice, dbOffice);
System.setProperty(DB_OFFICE, dbOffice);
System.setProperty(DB_CONNECTION_INIT, initScript);
System.setProperty(DB_VALIDATION_QUERY, "SELECT 1 FROM dual");
System.setProperty(DB_URL, System.getProperty("testcontainer.cwms.bypass.url"));
System.setProperty(DB_USERNAME, System.getProperty("testcontainer.cwms.bypass.office.eroc") + "WEBTEST");
Expand All @@ -210,7 +204,6 @@ private static void setupDbForBypass(DbType dbType)
String validationQuery = "SELECT 1";
System.setProperty(DB_DRIVER_CLASS, "org.postgresql.Driver");
System.setProperty(DB_DATASOURCE_CLASS, DataSourceFactory.class.getName());
System.setProperty(DB_CONNECTION_INIT, validationQuery);
System.setProperty(DB_VALIDATION_QUERY, validationQuery);
System.setProperty(DB_URL, System.getProperty("testcontainer.opentsdb.bypass.url"));
System.setProperty(DB_USERNAME, System.getProperty("testcontainer.opentsdb.bypass.username"));
Expand Down Expand Up @@ -265,14 +258,13 @@ private static void startDbContainer(Configuration config, DbType dbType) throws
for(var k: props.keySet())
{
final String value = props.getProperty(k.toString(), null);
if (k != null && value != null)
if (value != null && !value.isBlank())
{
stmt.setString(1, k.toString());
stmt.setString(2, value);
stmt.executeUpdate();
}
}
//stmt.executeBatch();
}
catch (Throwable ex)
{
Expand All @@ -285,17 +277,13 @@ private static void startDbContainer(Configuration config, DbType dbType) throws
{
System.setProperty(DB_DRIVER_CLASS, "oracle.jdbc.driver.OracleDriver");
System.setProperty(DB_DATASOURCE_CLASS, "org.apache.tomcat.jdbc.pool.DataSourceFactory");
String dbOffice = System.getProperty(DB_OFFICE);
String initScript = String.format("BEGIN cwms_ccp_vpd.set_ccp_session_ctx(cwms_util.get_office_code('%s'), 2, '%s' ); END;", dbOffice, dbOffice);
System.setProperty(DB_CONNECTION_INIT, initScript);
System.setProperty(DB_VALIDATION_QUERY, "SELECT 1 FROM dual");
}
else
{
String validationQuery = "SELECT 1";
System.setProperty(DB_DRIVER_CLASS, "org.postgresql.Driver");
System.setProperty(DB_DATASOURCE_CLASS, "org.apache.tomcat.jdbc.pool.DataSourceFactory");
System.setProperty(DB_CONNECTION_INIT, validationQuery);
System.setProperty(DB_VALIDATION_QUERY, validationQuery);
}
setupClientUser(dbType);
Expand All @@ -308,32 +296,24 @@ private static void setupClientUser(DbType dbType)
{
// I have no idea why this is suddenly required but it was also affecting operations in
// runtime test environments where the required entries weren't present.
String unlockUser = "begin cwms_sec.unlock_user(?,?); end;";
String userPermissions = "begin execute immediate 'grant web_user to ' || ?; end;";
String dbOffice = System.getProperty(DB_OFFICE);
String setWebUserPermissions = "begin\n" +
" cwms_sec.add_user_to_group(?, 'CWMS User Admins',?) ;\n" +
" commit;\n" +
"end;";
String userPermissions2 = "begin cwms_sec.ADD_USER_TO_GROUP(?, 'CWMS PD Users', 'HQ'); end;";
try(Connection connection = DriverManager.getConnection(System.getProperty(DB_URL), "CWMS_20",
System.getProperty(DB_PASSWORD));
PreparedStatement unlockUserStmt = connection.prepareStatement(unlockUser);
PreparedStatement userPermissionsStmt = connection.prepareStatement(userPermissions);
PreparedStatement setWebUserPermissionsStmt = connection.prepareStatement(setWebUserPermissions))
System.getProperty(DB_PASSWORD)))
{
final String username = System.getProperty(DB_USERNAME);
unlockUserStmt.setString(1, username);
unlockUserStmt.setString(2, dbOffice);
unlockUserStmt.executeQuery();
userPermissionsStmt.setString(1, username);
userPermissionsStmt.executeQuery();
setWebUserPermissionsStmt.setString(1, username);
setWebUserPermissionsStmt.setString(2, dbOffice);
setWebUserPermissionsStmt.executeQuery();
try(PreparedStatement stmt1 = connection.prepareStatement(userPermissions);
PreparedStatement stmt2 = connection.prepareStatement(userPermissions2))
{
String username = System.getProperty(DB_USERNAME);
stmt1.setString(1, username);
stmt1.executeQuery();
stmt2.setString(1, username);
stmt2.executeQuery();
}
}
catch(SQLException ex)
{
log.atDebug().setCause(ex).log("Error setting up client user");
log.atDebug().setCause(ex).log("Error setting up web user");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Objects;

import decodes.util.DecodesSettings;
import jakarta.servlet.http.HttpServletResponse;

import io.restassured.RestAssured;
Expand Down Expand Up @@ -63,6 +65,18 @@ public static TomcatServer getCurrentTomcat()
return currentTomcat;
}

public static String getOrganization()
{
try
{
return getCurrentConfig().getOpenDcsDatabase().getSettings(DecodesSettings.class).orElseThrow().CwmsOfficeId;
}
catch(Throwable e)
{
throw new IllegalStateException(e);
}
}

@Override
public void beforeEach(ExtensionContext context) throws Exception
{
Expand Down Expand Up @@ -107,7 +121,7 @@ private static void healthCheck() throws InterruptedException
log.debug("Server is up!");
break;
}
catch(Throwable ex)
catch(AssertionError ex)
{
log.atDebug().setCause(ex).log("Waiting for the server to start...");
Thread.sleep(100);//NOSONAR
Expand All @@ -125,10 +139,11 @@ private void setupClientUser()
{
String userPermissions = "begin execute immediate 'grant web_user to " + System.getProperty("DB_USERNAME") + "'; end;";
String dbOffice = System.getProperty("DB_OFFICE");
String setWebUserPermissions = "begin\n" +
" cwms_sec.add_user_to_group(?, 'CWMS User Admins',?) ;\n" +
" commit;\n" +
"end;";
String setWebUserPermissions = """
begin
cwms_sec.add_user_to_group(?, 'CWMS User Admins',?) ;
commit;
end;""";
try(Connection connection = DriverManager.getConnection(System.getProperty("DB_URL"), "CWMS_20",
System.getProperty("DB_PASSWORD"));
PreparedStatement stmt1 = connection.prepareStatement(userPermissions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import org.opendcs.odcsapi.fixtures.DatabaseSetupExtension;
import org.opendcs.odcsapi.fixtures.DbType;
import org.opendcs.odcsapi.fixtures.TomcatServer;
import org.opendcs.odcsapi.hydrojson.DbInterface;
import org.opendcs.odcsapi.res.ObjectMapperContextResolver;
import org.opendcs.odcsapi.sec.OpenDcsApiRoles;
import org.opendcs.odcsapi.sec.OpenDcsPrincipal;
Expand All @@ -56,7 +55,7 @@
import static io.restassured.RestAssured.given;
import static java.util.stream.Collectors.joining;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.opendcs.odcsapi.util.ApiConstants.ORGANIZATION_HEADER;

class BaseIT
{
Expand Down Expand Up @@ -147,7 +146,11 @@ void authenticate()
.setMaxAge(-1)
.setPath("/odcsapi")
.build();
authSpec = new RequestSpecBuilder().addCookie(cookie).build();
String organization = DatabaseSetupExtension.getOrganization();
authSpec = new RequestSpecBuilder()
.addCookie(cookie)
.addHeader(ORGANIZATION_HEADER, organization)
.build();
//Check while passing in cookie
given()
.log().ifValidationFails(LogDetail.ALL, true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2025 OpenDCS Consortium and its Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.opendcs.odcsapi.res.it;


import io.restassured.filter.log.LogDetail;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.core.MediaType;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
import org.opendcs.odcsapi.fixtures.DatabaseContextProvider;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;

@Tag("integration-cwms-only")
@ExtendWith(DatabaseContextProvider.class)
final class OrganizationResourcesIT extends BaseIT
{

@TestTemplate
void getAlgorithmRefs()
{
given()
.log().ifValidationFails(LogDetail.ALL, true)
.accept(MediaType.APPLICATION_JSON)
.when()
.redirects().follow(true)
.redirects().max(3)
.get("organizations")
.then()
.log().ifValidationFails(LogDetail.ALL, true)
.assertThat()
.statusCode(is(HttpServletResponse.SC_OK))
.body("name", hasItem("SPK"))
;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,14 @@ void unauthorizedAccessShouldReturn401()
//ensures unauthorized session
.filter(new SessionFilter())
.when();
Response response;
switch(method)
Response response = switch(method)
{
case GET:
response = spec.get(path);
break;
case POST:
response = spec.post(path);
break;
case PUT:
response = spec.put(path);
break;
case DELETE:
response = spec.delete(path);
break;
default:
throw new IllegalArgumentException("Unsupported method: " + method);
}
case GET -> spec.get(path);
case POST -> spec.post(path);
case PUT -> spec.put(path);
case DELETE -> spec.delete(path);
default -> throw new IllegalArgumentException("Unsupported method: " + method);
};
response.then()
.log().ifValidationFails(LogDetail.ALL, true)
.assertThat()
Expand All @@ -94,6 +84,7 @@ private static Stream<Endpoint> getEndpoints()
return paths.entrySet().stream()
.filter(e -> !e.getKey().equals("/credentials"))
.filter(e -> !e.getKey().equals("/logout"))
.filter(e -> !e.getKey().equals("/organizations"))
.flatMap(e ->
e.getValue().readOperationsMap().entrySet().stream().map(opEntry ->
{
Expand All @@ -114,20 +105,8 @@ private static Stream<Endpoint> getEndpoints()
}));
}

private static class Endpoint
private record Endpoint(String path, PathItem.HttpMethod method, String contentMediaType, String acceptMediaType)
{
private final String path;
private final PathItem.HttpMethod method;
public final String contentMediaType;
public final String acceptMediaType;

private Endpoint(String path, PathItem.HttpMethod method, String contentMediaType, String acceptMediaType)
{
this.path = path;
this.method = method;
this.contentMediaType = contentMediaType;
this.acceptMediaType = acceptMediaType;
}

@Override
public String toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
username="${DB_USERNAME}"
password="${DB_PASSWORD}"
driverClassName="${DB_DRIVER_CLASS}"
initSQL="${DB_CONNECTION_INIT}"
logAbandoned="true"
url="${DB_URL}"
logValidationErrors="true"
validationQuery="${DB_VALIDATION_QUERY}"
testOnBorrow="true"
maxActive="10"
maxIdle="4"
minIdle="1"/>
Expand Down
1 change: 1 addition & 0 deletions opendcs-rest-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dependencies {
exclude group: "org.eclipse.jetty", module: "jetty-annotations"
}
implementation(libs.opendcs.api)
implementation(libs.jdbi)
swaggerDeps(libs.servlet.api)
swaggerDeps(libs.rs.api)
swaggerDeps(libs.swagger.jaxrs2)
Expand Down
Loading
Loading