Create, Update, Delete Data on T7 CDA using JavaScript/React
This document shows you how to write data to your local T7 using the web browser. These instructions are also available on GitHub.
Important
Introduction
In order to manipulate data in the database in some fashion you need to be authorized.
Unlike READ (GET) requests that are read-only
, changing or altering data requires you to login.
As a means of allowing districts to start altering data in their databases a series of programs were created in tomcat (CDA runs in Tomcat) to handle the login process.
These programs (WAR files) get installed on your T7 by G6.
They (G6) also need to alter your Tomcat settings and Apache settings to enable this.
To get CWMSLogin working just to be able to get an API key, you could follow the steps outlined in the cwms-python docs (Setting up CDA writes and cwms-python on T7s). This API key is ONLY used for backend processes.
⚠ IT SHOULD NOT be placed in your client-side javascript. ⚠ This exposes it to anyone that can get to the page and would give them the same permissions in the database as the user that creates the key.
You can NOT write to the national CDA instance. I.e. https://cwms-data.usace.army.mil/cwms-data
.
This is a largely read only instance. If you did find some way to write to it dataguard would overwrite it. Data is pushed from district T7s, currently, to the national database and the above mentioned URL gives you that data, publicly.
A local CDA instance will need to be placed in your Tomcat web-apps
.
The process for that is outlined here:
Install CDA for district T7
Getting Started
If you do not have any of the login setup completed:
- You can submit a "CWMS Helpdesk" ticket
- In Service Now search for "CWMS" and select the CWMS ticket
- Target the
WEB
team with it set asNOT
critical.- This will go directly to Mark and his team.
- In the description specify "CDA Auth enabled for T7. Apache reverse proxy for CDA auth in JS. Setup 404 redirects for "/path" for react client-side routing. Where "/path" is the path you wish to deploy your react distribution files to. If this is root you would say "/" ONLY if you do not have a site already. Eventually you would have this updated to root as you have all your pages migrated."
- You can submit a "CWMS Helpdesk" ticket
Once G6 has confirmed this working with you try the following:
- Navigate to:
- https://wm.ds.<3letter>.usace.army.mil:8243/<3letter>-data/CWMSLogin/login - where <3letter> would be swt for example
- Click accept and login.
- ⚠ If you get an error about no permissions, you will need to be granted permissions via the serveradmin.exe utility in CWMS ⚠
- Once logged in you should see the permissions you currently have
- Attempt the reverse proxy AFTER you login to the tomcat port above
- https://wm.ds.<3letter>.usace.army.mil:8243/CWMSLogin/login - where <3letter> would be swt for example
- You should see the same message you saw above.
- If you get any other errors, please screenshot and send them to the G6 rep working with you (Probably Mark Carron)
- https://wm.ds.<3letter>.usace.army.mil:8243/CWMSLogin/login - where <3letter> would be swt for example
- Navigate to:
Writing code
Now that you have everything setup, you are ready to access and write to Oracle on your T7 via CDA.
The general idea/workflow is as follows:
- User navigates to your page
- Javascript does a polling request (every 5-10 seconds) to the auth endpoint to see if it gets a
401 Unauthorized
error - If authorized, changes button to say "Submit"
- Clicking this button fires POST requests you define in your code
- If NOT authorized, button says the text "Login"
- Clicking this button would direct the user to :8243/CWMSLogin/login?OriginalLocation=URL/You/Came/From
- Once the user clicks accept a "JSESSIONIDSSO" token is placed in the users cookies, this gets passed to the server on each request as a form of verifying who you are. Clearing your cookies can reset the login. It will also timeout after some time. (This is why you must poll)
- GET data could be populated for view (logged in or not)
- If the user is logged in you could also enable input boxes for example
- User clicks submit, various input boxes on the page get data pulled from them
- Data is sent via
cwmsjs
orfetch/vanillajs
to T7 CDA. CWMSjs can be used with vanilla js or react. - User gets feedback from the push requests on if data was written or if they are not authorized again (could become unauthorized in between polling auth checks)
In order to return you back after step 2bb includes a OriginalLocation
, you could get clever as I do in the example and use javascript to provide this.
This makes it work on your COOP too!
Code Examples
- I have prepared a few very basic code examples in both vanilla javascript and react (groundwork/etc capable) that show you how you could handle this.
- ⚠ If you run into issues with either please report them to so they can fix / correct for all.
Javascript
React
- Writing CLOB data using CWMSjs HERE - CWMSjs saves you from having to write/create the URL yourselves.
CWMSjs
CWMSjs is a wrapper around CDA It is written in typescript and resides in NPM
This makes it so you can just
npm i cwmsjs
and start using it. It offers many examples for READ, but since it is public the authorization page is a little... generic.Additional CWMSjs docs here: - Examples directory : here - Authorization example JS / React: here
T7 Deployment
In order to use this javascript with your local CDA instance on your T7 the source will need to live in tomcat or in apache/httpd.
If you place the client-side source (React/JS/Html/css) in tomcat you will not need the reverse proxy.
Also you can run this command if using React/Groundwork/etc npm run build
This will trigger a script you have setup in the scripts block of your package.json
to create distribution files dist
in the same directory as the package.json. It will be grayed out because it is not in the version control (it's in the .gitignore).
Once you run the build command you can copy the contents of ./dist
to wherever you would like the site to live. Side note: the current process for the DEV of our PUBLIC site has a similar script in package.json
of your WM public site to copy to a S3 bucket using github / AWS secrets.
Here is a script i have in my package.json that builds and deploys me internal site react distribution files to our T7 using a putty profile I created with a keypair in it named CWPT7
My full script block in package.json
:
"scripts": { "dev": "vite", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", "clean-remote": "plink -batch -load CWPT7 \"cd /wm/swt/wm_web/var/apache2/2.4/htdocs/assets/ && rm *.js && rm *.css\"", "deploy": "npm run build && npm run clean-remote && pscp -batch -r ./dist/assets/* CWPT7:/wm/swt/wm_web/var/apache2/2.4/htdocs/assets/ && pscp -batch -r ./dist/index.html CWPT7:/wm/swt/wm_web/var/apache2/2.4/htdocs/", "deploy-all": "npm run build && npm run clean-remote && pscp -batch -r ./dist/* CWPT7:/wm/swt/wm_web/var/apache2/2.4/htdocs/", "preview": "vite preview" },
Take notice that i have a deploy-all
and deploy
script. I run the deploy-all
when I want EVERY file to get uploaded (including images). So that the process is faster my regular deploy
command pushes only the important stuff (CSS/JS/HTML files).
The full command to trigger these scripts you can define in the scripts
tag are:npm run deploy
npm run deploy-all
⚠ Gotchas ⁉
- Users MUST
npm run build
and push theirdist
files to their T7 web directory in order for the authentication to work.- This is because
localhost:5173
is a different port/host thanhttpd/tomcat
- This is because
- If you attempt to go to the reverse proxy first (before the :8243/CWMSLogin/login tomcat) you will get a 400 error message. This is due to the process failing to pass the certs up stream. We are looking into it. For now send your users to tomcat to authenticate.
- Then redirect back to httpd. The reverse proxy shares the certs.
- When the T7 go away the login process will change slightly, but the code to POST will be the same.
- The endpoints will change some. I.e. no more
CWMSLogin/login
- Majority of your code stays the same!
- The endpoints will change some. I.e. no more
-- Charles Graham