From 02cc4400a345ce9c83c59b21b40f6cab03f79122 Mon Sep 17 00:00:00 2001 From: David Gauldie Date: Tue, 4 Jun 2024 10:39:39 -0400 Subject: [PATCH] 3668 link devs to openstack (#3749) Co-authored-by: dgauldie --- README.md | 2 +- containers/scripts/docker-compose-hmi.yml | 8 +- containers/secrets.env.encrypted | 94 ++- docker-bake.hcl | 4 - hmiServerDev.sh | 21 +- package.json | 1 + packages/client/hmi-client/package.json | 1 + .../client/hmi-client/vite.config.staging.ts | 23 + packages/client/hmi-client/vite.config.ts | 6 +- packages/server/README.md | 6 +- .../knowledge/KnowledgeController.java | 742 ++++++++++-------- .../hmiserver/utils/rebac/ReBACService.java | 206 ++--- .../utils/rebac/askem/RebacUser.java | 21 +- .../main/resources/application-ide.properties | 33 - .../application-local-keycloak.properties | 83 ++ .../resources/application-local.properties | 83 +- .../resources/application-remote.properties | 8 - .../application-secrets.properties.encrypted | 119 ++- ...> application-staging-keycloak.properties} | 87 +- .../resources/application-staging.properties | 104 +++ .../src/main/resources/application.properties | 81 +- .../src/main/resources/messages.properties | 36 +- .../configuration/TestReBACService.java | 14 + .../knowledge/KnowledgeControllerTests.java | 12 +- .../resources/application-test.properties | 115 ++- 25 files changed, 1134 insertions(+), 776 deletions(-) create mode 100644 packages/client/hmi-client/vite.config.staging.ts delete mode 100644 packages/server/src/main/resources/application-ide.properties delete mode 100644 packages/server/src/main/resources/application-remote.properties rename packages/server/src/main/resources/{application-beta.properties => application-staging-keycloak.properties} (57%) create mode 100644 packages/server/src/main/resources/application-staging.properties diff --git a/README.md b/README.md index c14a66680e..709a88bc5c 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ To generate the typescript models as a single command: yarn workspace @uncharted/server-type-generator run generateTypes ``` -The client, when running with the command `yarn dev`, connects to the server in the staging environment, enabling client-side development without the need to spin up the server locally. +The client, when running with the command `yarn dev`, connects to the server in the dev environment, enabling client-side development without the need to spin up the server locally. To run the client while connecting to the server running locally, use the following command: diff --git a/containers/scripts/docker-compose-hmi.yml b/containers/scripts/docker-compose-hmi.yml index d586d38174..366184a144 100644 --- a/containers/scripts/docker-compose-hmi.yml +++ b/containers/scripts/docker-compose-hmi.yml @@ -59,10 +59,10 @@ services: # GITHUB_URL: https://api.github.com # JSDELIVR_URL: https://cdn.jsdelivr.net # MIRA-API_URL: http://34.230.33.149:8771 - # MIT-PROXY_URL: https://mit-proxy.staging.terarium.ai - # SKEMA-PY_URL: https://skema-py.staging.terarium.ai - # SKEMA-RS_URL: https://skema-rs.staging.terarium.ai - # SKEMA-UNIFIED_URL: https://skema-unified.staging.terarium.ai + # MIT-PROXY_URL: https://mit-proxy.dev.terarium.ai + # SKEMA-PY_URL: https://skema-py.dev.terarium.ai + # SKEMA-RS_URL: https://skema-rs.dev.terarium.ai + # SKEMA-UNIFIED_URL: https://skema-unified.dev.terarium.ai # XDD-DEV-SERVICE_URL: https://xdddev.chtc.io # XDD-PROD-SERVICE_URL: https://xdd.wisc.edu depends_on: diff --git a/containers/secrets.env.encrypted b/containers/secrets.env.encrypted index 6d1e4e988c..5e1fc23734 100644 --- a/containers/secrets.env.encrypted +++ b/containers/secrets.env.encrypted @@ -1,50 +1,46 @@ $ANSIBLE_VAULT;1.1;AES256 -37393138363663633036663466663737646333646230333766633139376463383131333433646563 -6438646234343638383765636366333633623932333035340a656632626337616238393739613238 -64363632313664613233303865343662366262353831353935373534336262626239316137316362 -6339323565333931650a663830343162636366323563343835613139613431643332306261316332 -64353936383539383232636665353562343161616430343330373866613139663931666466663766 -64616664346230666661666235333830633734386533613438316136333766366239353433613365 -34353839336339643165313764396434366535363033313336633735303037656466333233653035 -66353731343066333965663462633638396463623463626630303963313333366331313062636433 -64663562366562653635643139343131313765393537343032613436323336626336356432613164 -34653132346430643135623734626265396263396433663833363163366139393733326462613935 -38643461633337383364383562306566643535353364663637626264626365646535353865636131 -32316465316639346630653839386565636461363336366339303836323433363763666261613836 -37343238633635626364396266393431653735333730623764336432643063373838366161303637 -38383132386261616534643932646236333831333363336664663536306436313135333733323739 -39313234313164653931353334646265393234376262656236393733666334393765636162353165 -32343737663839316634363137616163656239613035313539396236343965346466366663336564 -37653135656362316434336135323731396134626132373466353265613062343463373537663365 -63656332623966636439333762633738353362346434333731633334643932383761323535633937 -65313434363932616164343234393038376233663239356336366664306136336635346564303630 -32663065373031353035623837346562396633666363393331313134386464663831666637643661 -63636564383461333439306565343738396261376361373234323433623532373030653731383562 -31313966663730356563653234633761613038646163303665656261333835313932613362613533 -66663062323534346263376130323630383031343038356435643538636665313432613764643131 -66396539393031626236333565623062303232623363633632303434626664373435353364323966 -30323936663631386364616431316331656634323636343433353636356463333639393036613533 -37333732623032313735363633346363633066303565316437343231316636313134316633373761 -63646563316366343362646561633637323530653364343263626633336539646163633561383335 -34613862393031616362386661353630393430383935373838663031363563643566393138393461 -30636130616331616164306363366565353837623061356265366236363733633735306537356261 -32366331613135656163393930663563326139333961363338393565346130323337633966383931 -39333431393566626562653137663938623336383231626162643063636232626361323535626538 -38393033366131383133393636616437353365333562346136343038373132346466653536313732 -34623538656235616436616631383833306432383736333736353434323464373333353263633561 -62336164653061376135663964396533363431383763613865373564393961646266613939656465 -65666132303933623336616337346464356163333238616437646430656139336461396334316262 -37353763303835383438653739303365343931663330653235636230613838373464366266653134 -30616463343538326261653637323162343439613466346564356631303936633830613362643866 -66356133323564306237353235343436616661333938653538363236613764313730653535353034 -65376135323533333637646537616335373464393739393133333739616665323864376437386635 -30356561346339653835376666376437663136616230333633646161356630383834306233303839 -39333265363162333664336563643365613736336534653832393563323937363331333233353531 -62666264366235623962396362363231313162383530646461376534393965333439336630363230 -31616639613939356634323733343633623833643036373635323061353837376361373663623461 -65646166336632326636666439623239623134313864653435613838656135333163643964393233 -38666533613866326561313335333238343565616561323932386134343966393139333636616266 -62386563393864366231636662353736633239386263656362343832636165396130363264633831 -39306462316432646233303162633365643332313766356234386633616563343561336339343564 -65323835383535646465303064636136343135663938376162623639343464323333613838623334 -62633066633838663335383365363063353532386264613038633232666166336563 +30613836356630646138643263303632386439626634386237366239616466613131373765376632 +3666383538303637393437633639303761313366343461630a323230613839313939313832343537 +36643437643237613564363331366238366266356261303238343436353230393737306633663733 +3930656162323839390a326166613537666535356236396337376532656131666237316537313961 +66663361666565353136316339373338653466313962353431303534316464656264343539653739 +61383061666432633430336331623066393065353839653331396263353162366433646163363635 +65326530396263636464393135613636373235616331616564616331303433313137326330366639 +31633165313030343431376232333337643236346465353935366237643262306165666165633964 +31623866383564376332656566306635393130613433633438313964383865366630383932363365 +66326462346137623130326262313538653038666533393133356632653438616139393738393630 +35313535653930376135323661663364323935656534633539613266613838636238643264326165 +62323563366231333038663366376263636166353935623930626437396365623430303032373664 +38336161313437386433653766393265613364383836343939613630363132653837333433363637 +64386539643330336530663063326662336435363537396562613838656231326434373363393462 +32636637353536613263323439343737326636666563323632396439383833396438373334346132 +65353234663762363535363730376334396332373064666239646364353238653337653061656562 +66376635326361306363653933663164383432303933383965343839643930656535393938363932 +31376537313634356430323134343761633762363231343835663330633439646463376338353362 +63316130343462323966663937323534353434313238373832636361306263636165346166613531 +36323265373638333337623634653832383233366335386162373466373339633164346563376464 +65353462633633383764646663636231633032346564623431633438636461326464613834626663 +38636431313664333062626261616562376366313333356537336664333364623035646666616261 +64356434663036616363343263613432653637353936333134626330393265393732333665336630 +38313665616662386231666462353138323665646331623965353263373466386462333563633332 +37656631383333626436326536353833623130393531306530623435353736666566613738343332 +34633037643665343331616530376130383662646166666639373466343133323537643233366331 +31333564623734656661383139363732383034323766343461303431656633306138316437343637 +32316138633533666262613462636133393963613736656234663338633439633730623764626531 +38343866316461393833613935636130363535323064653863396436636434613732306633323231 +38316162303163646265303337343339643734303633316230396361326266643034393266636537 +34623963636463393562326633653363653531373666616532376338383431383662643231346433 +38333733386636313365616232393033643164653266386438333864623565363631656230393266 +32313038343037626338656564313463363231313331333531656663343738343435313663633234 +35346638663534343131383163336235306432353235363264633862383730626535333666643337 +61623232383834383366663761333331303531376636653638653938353837633764613639303966 +39393133643466326461323836663964363931613730343930323835633931396236336239616362 +34346165366334646164343463383361626266613366666432353265633766653232383264333862 +64346130326461316135653265306134666463343063336231353565616532656562373533336432 +61626537383065393830323232343330353661616363636536396332656330303062353833316161 +36343030353464656532613561333437333637336661616431643964643134656134353763323537 +62613664383331633135363063653436633565323830643536633061326331393038666564313932 +37316266653964393232396561316563646134383463613332346665316137393562663438643136 +33363937623536336337373162636438323737306235363537343863343137633036613162366664 +38303636643435323866396662636361643264633835623666336538323339306334306562303239 +6538 diff --git a/docker-bake.hcl b/docker-bake.hcl index 5ff8afb4da..3c9c0865c2 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -29,10 +29,6 @@ group "prod" { targets = ["hmi-client", "hmi-server", "gollm-taskrunner", "mira-taskrunner", "funman-taskrunner"] } -group "staging" { - targets = ["hmi-client", "hmi-server", "gollm-taskrunner", "mira-taskrunner", "funman-taskrunner"] -} - group "default" { targets = ["hmi-client-base", "hmi-server-base", "gollm-taskrunner-base", "mira-taskrunner-base", "funman-taskrunner-base"] } diff --git a/hmiServerDev.sh b/hmiServerDev.sh index 5d23a51eb6..6db9ca4090 100755 --- a/hmiServerDev.sh +++ b/hmiServerDev.sh @@ -80,6 +80,13 @@ function start_local() { cd - || exit } +function start_staging() { + echo "Starting local server" + cd ${SERVER_DIR} || exit + ./gradlew bootRun --args='--spring.profiles.active=default,secrets,staging' + cd - || exit +} + function build_docker_compose() { cat containers/common.env containers/secrets.env > containers/.env docker compose --env-file containers/.env --file containers/docker-compose-full.yml $(for customfile in `ls docker-compose.custom*.y*ml 2> /dev/null`; do echo -n " -f $customfile"; done) config > ./docker-compose.yml @@ -124,7 +131,7 @@ COMMAND=${COMMAND:-"help"} ENVIRONMENT=${ENVIRONMENT:-"local"} SERVER=${SERVER:-"false"} -VALID_ENVIRONMENTS=("local" "full" "ll") +VALID_ENVIRONMENTS=("local" "staging" "full" "ll") ENVIRONMENT_IS_VALID=0 for env in ${VALID_ENVIRONMENTS[@]}; do echo "checking $ENVIRONMENT against $env" @@ -150,6 +157,9 @@ case ${COMMAND} in local) deploy_local ;; + staging) + deploy_local + ;; full) deploy_full ;; @@ -160,6 +170,8 @@ case ${COMMAND} in if [ ${SERVER} == "run" ]; then if [ ${ENVIRONMENT} == "local" ]; then start_local + elif [ ${ENVIRONMENT} == "staging" ]; then + start_staging fi delete_secrets fi @@ -170,6 +182,9 @@ case ${COMMAND} in local) stop_local ;; + staging) + stop_local + ;; full) stop_full ;; @@ -200,14 +215,14 @@ case ${COMMAND} in start ENVIRONMENT - local | full | ll (default: local) Indicate which environment to develop against + local | staging | full | ll (default: local) Indicate which environment to develop against (ll: local_lean to run local with the absolute minimal support to run hmiServer for development) run (default: null) Indicate whether to run the server after starting the containers stop ENVIRONMENT - local | full (default: local) Indicate which containers to stop + local | staging | full | ll (default: local) Indicate which containers to stop OTHER COMMANDS: encrypt diff --git a/package.json b/package.json index b8586eaebc..ece26f787c 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "build": "yarn workspaces foreach --all --parallel --interlaced --verbose --topological run build", "dev": "yarn workspace hmi-client run dev", "local": "yarn workspace hmi-client run local", + "staging": "yarn workspace hmi-client run staging", "generateTypes": "yarn workspace @uncharted/server-type-generator run generateTypes", "serve": "yarn workspace hmi-client run build", "lint": "eslint . --ext .ts,.vue --fix --cache", diff --git a/packages/client/hmi-client/package.json b/packages/client/hmi-client/package.json index 918f8bbdb8..571a966cb9 100644 --- a/packages/client/hmi-client/package.json +++ b/packages/client/hmi-client/package.json @@ -5,6 +5,7 @@ "scripts": { "dev": "yarn install && vite --host", "local": "yarn install && vite --host --config vite.config.local.ts", + "staging": "yarn install && vite --host --config vite.config.staging.ts", "build": "vue-tsc --noEmit && vite build", "typecheck": "yarn workspace graph-scaffolder tsc --build && vue-tsc --noEmit", "preview": "vite preview", diff --git a/packages/client/hmi-client/vite.config.staging.ts b/packages/client/hmi-client/vite.config.staging.ts new file mode 100644 index 0000000000..6874913902 --- /dev/null +++ b/packages/client/hmi-client/vite.config.staging.ts @@ -0,0 +1,23 @@ +/// +import config from './vite.config'; + +config.server.proxy = { + '^/api': { + target: 'https://server.staging.terarium.ai', + rewrite: (path_str) => path_str.replace(/^\/api/, ''), + changeOrigin: true + }, + '^/beaker': { + target: 'https://beaker.staging.terarium.ai', + changeOrigin: true, + rewrite: (path_str) => path_str.replace(/^\/beaker/, '') + }, + '^/beaker_ws': { + target: 'ws://beaker.staging.terarium.ai', + ws: true, + changeOrigin: true, + rewrite: (path_str) => path_str.replace(/^\/beaker/, '') + } +}; + +export default config; diff --git a/packages/client/hmi-client/vite.config.ts b/packages/client/hmi-client/vite.config.ts index 949ac27d75..bec21b9486 100644 --- a/packages/client/hmi-client/vite.config.ts +++ b/packages/client/hmi-client/vite.config.ts @@ -44,17 +44,17 @@ export default defineConfig({ }, proxy: { '^/api': { - target: 'https://server.staging.terarium.ai', + target: 'https://server.dev.terarium.ai', rewrite: (path_str) => path_str.replace(/^\/api/, ''), changeOrigin: true }, '^/beaker': { - target: 'https://beaker.staging.terarium.ai', + target: 'https://beaker.dev.terarium.ai', changeOrigin: true, rewrite: (path_str) => path_str.replace(/^\/beaker/, '') }, '^/beaker_ws': { - target: 'ws://beaker.staging.terarium.ai', + target: 'ws://beaker.dev.terarium.ai', ws: true, changeOrigin: true, rewrite: (path_str) => path_str.replace(/^\/beaker/, '') diff --git a/packages/server/README.md b/packages/server/README.md index 2297e68614..84ef5502cd 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -140,16 +140,16 @@ class Parent { class Child { @Id - private UUID id = UUID.randomUUID(); + private final UUID id = UUID.randomUUID(); -}; +} ``` ## Migrations: There are two "passes" for migrations in the app. -1) For local, staging, and prod we have `spring.jpa.hibernate.ddl-auto=update`. On server startup Hibernate will update the schema if it detects that the entities and tables/columns are out of sync. It will add new tables/columns and update existing ones as needed, but it won't delete any existing tables or columns. +1) For local, dev, staging, and prod we have `spring.jpa.hibernate.ddl-auto=update`. On server startup Hibernate will update the schema if it detects that the entities and tables/columns are out of sync. It will add new tables/columns and update existing ones as needed, but it won't delete any existing tables or columns. This ensures that new tables are created and new columns are added. However this leaves the case of _modifying existing columns_. diff --git a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/controller/knowledge/KnowledgeController.java b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/controller/knowledge/KnowledgeController.java index 898847b99b..55944678a1 100644 --- a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/controller/knowledge/KnowledgeController.java +++ b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/controller/knowledge/KnowledgeController.java @@ -69,6 +69,7 @@ import software.uncharted.terarium.hmiserver.service.data.ProvenanceSearchService; import software.uncharted.terarium.hmiserver.service.data.ProvenanceService; import software.uncharted.terarium.hmiserver.utils.ByteMultipartFile; +import software.uncharted.terarium.hmiserver.utils.Messages; import software.uncharted.terarium.hmiserver.utils.StringMultipartFile; import software.uncharted.terarium.hmiserver.utils.rebac.Schema; @@ -96,6 +97,8 @@ public class KnowledgeController { final ProjectService projectService; final CurrentUserService currentUserService; + final Messages messages; + @Value("${mit-openai-api-key:}") String MIT_OPENAI_API_KEY; @@ -114,31 +117,7 @@ public ResponseEntity equationsToModel( final Model responseAMR; - // Get an AMR from Skema Unified Service - try { - responseAMR = skemaUnifiedProxy.consolidatedEquationsToAMR(req).getBody(); - - if (responseAMR == null) { - throw new ResponseStatusException( - HttpStatus.UNPROCESSABLE_ENTITY, - "Skema Unified Service did not return any AMR based on the provided Equations. This could be due to invalid equations or the inability to parse them into the requested framework."); - } - // Catch every exception thrown by the Proxy - } catch (final FeignException e) { - final String error = "Skema Unified Service did not return any AMR based on the provided Equations"; - log.error(error, e); - if (e.status() < 100) - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, error + ": " + e.getMessage()); - throw new ResponseStatusException(HttpStatus.valueOf(e.status()), error + ": " + e.getMessage()); - } catch (final Exception e) { - final String error = "Unable to reach Skema Unified Service"; - log.error(error, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, error + ": " + e.getMessage()); - } - - final String serviceSuccessMessage = "Skema Unified Service returned an AMR based on the provided Equations. "; - - // If no model id is provided, create a new model + // Check if a model ID is supplied and try to extract it UUID modelId = null; final String modelIdString = req.get("modelId") != null ? req.get("modelId").asText() : null; @@ -147,11 +126,28 @@ public ResponseEntity equationsToModel( // Get the model id if it is a valid UUID modelId = UUID.fromString(modelIdString); } catch (final IllegalArgumentException e) { - throw new ResponseStatusException( - HttpStatus.BAD_REQUEST, serviceSuccessMessage + "The provided modelId is not a valid UUID."); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, messages.get("generic.invalid-uuid")); + } + } + + // Get an AMR from Skema Unified Service + try { + responseAMR = skemaUnifiedProxy.consolidatedEquationsToAMR(req).getBody(); + if (responseAMR == null) { + throw new ResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY, messages.get("skema.bad-equations")); } + } catch (final FeignException e) { + final String error = "Skema Unified Service did not return a valid AMR based on the provided Equations"; + log.error(error, e); + + throw handleSkemaFeignException(e); + } catch (final Exception e) { + final String error = "An unhandled error occurred while processing the AMR from equations."; + log.error(error, e); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, messages.get("skema.internal-error")); } + // If no model id is provided, create a new model asset if (modelId == null) { try { final Model model = modelService.createAsset(responseAMR, permission); @@ -159,29 +155,28 @@ public ResponseEntity equationsToModel( } catch (final IOException e) { log.error("Unable to create a model", e); throw new ResponseStatusException( - org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, - serviceSuccessMessage - + "However, we encountered an issue creating the model. Please try again."); + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); } } - // If a model id is provided, update the model + // If a model id is provided, update the existing model + final Optional model; + + model = modelService.getAsset(modelId, permission); + if (model.isEmpty()) { + final String errorMessage = String.format("The model id %s does not exist.", modelId); + log.error(errorMessage); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, messages.get("model.not-found")); + } + + responseAMR.setId(model.get().getId()); try { - final Optional model = modelService.getAsset(modelId, permission); - if (model.isEmpty()) { - final String errorMessage = String.format("The model id %s does not exist.", modelId); - log.error(errorMessage); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, errorMessage); - } - responseAMR.setId(model.get().getId()); modelService.updateAsset(responseAMR, permission); return ResponseEntity.ok(model.get().getId()); - } catch (final IOException e) { - log.error("Unable to update the model id {}.", modelId, e); + log.error("Unable to update the model with id {}.", modelId, e); throw new ResponseStatusException( - org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, - serviceSuccessMessage + "However, we encountered an issue updating the model. Please try again."); + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); } } @@ -193,9 +188,8 @@ public ResponseEntity base64EquationsToAMR(@RequestBody final JsonNode re } catch (final FeignException e) { final String error = "Error with Skema Unified Service while converting base64 equations to AMR"; log.error(error, e); - if (e.status() < 100) - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, error + ": " + e.getMessage()); - throw new ResponseStatusException(HttpStatus.valueOf(e.status()), error + ": " + e.getMessage()); + + throw handleSkemaFeignException(e); } } @@ -208,9 +202,8 @@ public ResponseEntity base64EquationsToLatex(@RequestBody final JsonNode } catch (final FeignException e) { final String error = "Error with Skema Unified Service while converting base64 equations to Latex"; log.error(error, e); - if (e.status() < 100) - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, error + ": " + e.getMessage()); - throw new ResponseStatusException(HttpStatus.valueOf(e.status()), error + ": " + e.getMessage()); + + throw handleSkemaFeignException(e); } } @@ -235,142 +228,164 @@ ResponseEntity postCodeToAMR( final Schema.Permission permission = projectService.checkPermissionCanWrite(currentUserService.get().getId(), projectId); - try { + final Optional code = codeService.getAsset(codeId, permission); + if (code.isEmpty()) { + log.error("Unable to fetch the requested code asset with codeId: {}", codeId); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, messages.get("code.not-found")); + } - final Code code = codeService.getAsset(codeId, permission).orElseThrow(); - final Map codeFiles = code.getFiles(); + final Map codeFiles = code.get().getFiles(); - final Map codeContent = new HashMap<>(); + final Map codeContent = new HashMap<>(); - for (final Entry file : codeFiles.entrySet()) { - final String filename = file.getKey(); - final CodeFile codeFile = file.getValue(); - final String content = - codeService.fetchFileAsString(codeId, filename).orElseThrow(); + for (final Entry file : codeFiles.entrySet()) { + final String filename = file.getKey(); + final CodeFile codeFile = file.getValue(); - if (dynamicsOnly - && codeFile.getDynamics() != null - && codeFile.getDynamics().getBlock() != null) { - final List blocks = codeFile.getDynamics().getBlock(); - for (final String block : blocks) { - final String[] parts = block.split("-"); - final int startLine = Integer.parseInt(parts[0].substring(1)); - final int endLine = Integer.parseInt(parts[1].substring(1)); + final String content; + try { + content = codeService.fetchFileAsString(codeId, filename).orElseThrow(); + } catch (final IOException e) { + log.error("Unable to fetch code as a string", e); + throw new ResponseStatusException( + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); + } - final String[] codeLines = content.split("\n"); - final List targetLines = - Arrays.asList(codeLines).subList(startLine - 1, endLine); + if (dynamicsOnly + && codeFile.getDynamics() != null + && codeFile.getDynamics().getBlock() != null) { + final List blocks = codeFile.getDynamics().getBlock(); + for (final String block : blocks) { + final String[] parts = block.split("-"); + final int startLine = Integer.parseInt(parts[0].substring(1)); + final int endLine = Integer.parseInt(parts[1].substring(1)); - final String targetBlock = String.join("\n", targetLines); + final String[] codeLines = content.split("\n"); + final List targetLines = Arrays.asList(codeLines).subList(startLine - 1, endLine); - codeContent.put(filename, targetBlock); - } - } else { - codeContent.put(filename, content); - dynamicsOnly = false; + final String targetBlock = String.join("\n", targetLines); + + codeContent.put(filename, targetBlock); } + } else { + codeContent.put(filename, content); + dynamicsOnly = false; } + } - final List files = new ArrayList<>(); - final List blobs = new ArrayList<>(); - - ResponseEntity resp = null; + final List files = new ArrayList<>(); + final List blobs = new ArrayList<>(); - try { - if (dynamicsOnly) { - for (final Entry entry : codeContent.entrySet()) { - files.add(entry.getKey()); - blobs.add(entry.getValue()); - } + ResponseEntity resp = null; - resp = skemaUnifiedProxy.snippetsToAMR(files, blobs); + if (dynamicsOnly) { + for (final Entry entry : codeContent.entrySet()) { + files.add(entry.getKey()); + blobs.add(entry.getValue()); + } - } else { - final ByteArrayOutputStream zipBuffer = new ByteArrayOutputStream(); - final ZipOutputStream zipf = new ZipOutputStream(zipBuffer, StandardCharsets.UTF_8); - - for (final Map.Entry entry : codeContent.entrySet()) { - final String codeName = entry.getKey(); - final String content = entry.getValue(); - final ZipEntry zipEntry = new ZipEntry(codeName); - zipf.putNextEntry(zipEntry); - zipf.write(content.getBytes(StandardCharsets.UTF_8)); - zipf.closeEntry(); - } - zipf.close(); + resp = skemaUnifiedProxy.snippetsToAMR(files, blobs); - final ByteMultipartFile file = - new ByteMultipartFile(zipBuffer.toByteArray(), "zip_file.zip", "application/zip"); + } else { + final ByteArrayOutputStream zipBuffer = new ByteArrayOutputStream(); + final ZipOutputStream zipf = new ZipOutputStream(zipBuffer, StandardCharsets.UTF_8); - resp = llmAssisted - ? skemaUnifiedProxy.llmCodebaseToAMR(file) - : skemaUnifiedProxy.codebaseToAMR(file); + try { + for (final Map.Entry entry : codeContent.entrySet()) { + final String codeName = entry.getKey(); + final String content = entry.getValue(); + final ZipEntry zipEntry = new ZipEntry(codeName); + zipf.putNextEntry(zipEntry); + zipf.write(content.getBytes(StandardCharsets.UTF_8)); + zipf.closeEntry(); + } + } catch (final IOException e) { + log.error("Unable to write to zip file", e); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, messages.get("generic.io-error")); + } finally { + try { + zipf.close(); + } catch (final IOException e) { + log.error("Unable to close zip file", e); + throw new ResponseStatusException( + HttpStatus.INTERNAL_SERVER_ERROR, messages.get("generic.io-error")); } - } catch (final FeignException e) { - final String error = "SKEMA was unable to create a model with the code provided"; - log.error(error, e); - throw new ResponseStatusException( - e.status() < 100 - ? org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY - : HttpStatus.valueOf(e.status()), - error + ": " + e.getMessage()); - } catch (final Exception e) { - log.error("Unable to get code to amr", e); - throw new ResponseStatusException( - org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, - "Unable to get code to amr: " + e.getMessage()); } - if (!resp.getStatusCode().is2xxSuccessful()) { - throw new ResponseStatusException(resp.getStatusCode(), "Unable to get code to amr from SKEMA"); - } + final ByteMultipartFile file = + new ByteMultipartFile(zipBuffer.toByteArray(), "zip_file.zip", "application/zip"); - Model model = mapper.treeToValue(resp.getBody(), Model.class); + resp = llmAssisted ? skemaUnifiedProxy.llmCodebaseToAMR(file) : skemaUnifiedProxy.codebaseToAMR(file); + } - if (model.getMetadata() == null) { - model.setMetadata(new ModelMetadata()); - } + if (resp.getStatusCode().is4xxClientError()) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("skema.bad-code")); + } else if (resp.getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("skema.service-unavailable")); + } else if (!resp.getStatusCode().is2xxSuccessful()) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("skema.internal-error")); + } - // create the model - if (!name.isEmpty()) { - model.setName(name); - } - if (model.getMetadata() == null) { - model.setMetadata(new ModelMetadata()); - } - model.getMetadata().setCodeId(codeId.toString()); + Model model; + try { + model = mapper.treeToValue(resp.getBody(), Model.class); + } catch (final IOException e) { + log.error("Unable to convert response to model", e); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, messages.get("generic.unknown")); + } - if (!description.isEmpty()) { - if (model.getHeader() == null) { - model.setHeader(new ModelHeader()); - } - model.getHeader().setDescription(description); - } - model = modelService.createAsset(model, permission); + if (model.getMetadata() == null) { + model.setMetadata(new ModelMetadata()); + } - // update the code - if (code.getMetadata() == null) { - code.setMetadata(new HashMap<>()); + // create the model + if (!name.isEmpty()) { + model.setName(name); + } + if (model.getMetadata() == null) { + model.setMetadata(new ModelMetadata()); + } + model.getMetadata().setCodeId(codeId.toString()); + + if (!description.isEmpty()) { + if (model.getHeader() == null) { + model.setHeader(new ModelHeader()); } - code.getMetadata().put("model_id", model.getId().toString()); - codeService.updateAsset(code, permission); + model.getHeader().setDescription(description); + } - // set the provenance - final Provenance provenancePayload = new Provenance( - ProvenanceRelationType.EXTRACTED_FROM, - model.getId(), - ProvenanceType.MODEL, - codeId, - ProvenanceType.CODE); - provenanceService.createProvenance(provenancePayload); + try { + model = modelService.createAsset(model, permission); + } catch (final IOException e) { + log.error("Unable to create model", e); + throw new ResponseStatusException( + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); + } - return ResponseEntity.ok(model); + // update the code + if (code.get().getMetadata() == null) { + code.get().setMetadata(new HashMap<>()); + } + code.get().getMetadata().put("model_id", model.getId().toString()); + try { + codeService.updateAsset(code.get(), permission); } catch (final IOException e) { - log.error("Unable to get code to amr", e); + log.error("Unable to update code", e); throw new ResponseStatusException( - org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, "Unable to get code to amr"); + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); } + + // set the provenance + final Provenance provenancePayload = new Provenance( + ProvenanceRelationType.EXTRACTED_FROM, + model.getId(), + ProvenanceType.MODEL, + codeId, + ProvenanceType.CODE); + provenanceService.createProvenance(provenancePayload); + + return ResponseEntity.ok(model); } // Create a model from code blocks @@ -400,44 +415,62 @@ ResponseEntity postCodeToAMR( public ResponseEntity codeBlocksToModel( @RequestParam(name = "project-id", required = false) final UUID projectId, @RequestPart final Code code, - @RequestPart("file") final MultipartFile input) - throws IOException { + @RequestPart("file") final MultipartFile input) { final Schema.Permission permission = projectService.checkPermissionCanWrite(currentUserService.get().getId(), projectId); + // 1. create code asset from code blocks + final Code createdCode; try { - // 1. create code asset from code blocks - final Code createdCode = codeService.createAsset(code, permission); + createdCode = codeService.createAsset(code, permission); + } catch (final IOException e) { + log.error("Unable to create code asset", e); + throw new ResponseStatusException( + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); + } - // 2. upload file to code asset - final byte[] fileAsBytes = input.getBytes(); - final HttpEntity fileEntity = new ByteArrayEntity(fileAsBytes, ContentType.TEXT_PLAIN); - final String filename = input.getOriginalFilename(); + // 2. upload file to code asset + final byte[] fileAsBytes; + try { + fileAsBytes = input.getBytes(); + } catch (final IOException e) { + log.error("Unable to read file", e); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, messages.get("generic.io-error")); + } + final HttpEntity fileEntity = new ByteArrayEntity(fileAsBytes, ContentType.TEXT_PLAIN); + final String filename = input.getOriginalFilename(); - if (filename == null) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "File name is required"); - } + if (filename == null) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, messages.get("code.filename-needed")); + } + try { codeService.uploadFile(code.getId(), filename, fileEntity); + } catch (final IOException e) { + log.error("Unable to upload file to code asset", e); + throw new ResponseStatusException( + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); + } - // add the code file to the code asset - final CodeFile codeFile = new CodeFile(); - codeFile.setFileNameAndProgrammingLanguage(filename); + // add the code file to the code asset + final CodeFile codeFile = new CodeFile(); + codeFile.setFileNameAndProgrammingLanguage(filename); - if (code.getFiles() == null) { - code.setFiles(new HashMap<>()); - } - code.getFiles().put(filename, codeFile); - codeService.updateAsset(code, permission); + if (code.getFiles() == null) { + code.setFiles(new HashMap<>()); + } + code.getFiles().put(filename, codeFile); - // 3. create model from code asset - return postCodeToAMR(createdCode.getId(), projectId, "temp model", "temp model description", false, false); + try { + codeService.updateAsset(code, permission); } catch (final IOException e) { - log.error("Unable to upload file", e); + log.error("Unable to update code asset", e); throw new ResponseStatusException( - org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, - "Error creating running code to model: " + e.getMessage()); + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); } + + // 3. create model from code asset + return postCodeToAMR(createdCode.getId(), projectId, "temp model", "temp model description", false, false); } /** @@ -453,85 +486,97 @@ public ResponseEntity postProfileModel( @PathVariable("model-id") final UUID modelId, @RequestParam(name = "project-id", required = false) final UUID projectId, @RequestParam(value = "document-id", required = false) final UUID documentId) { + final Schema.Permission permission = projectService.checkPermissionCanWrite(currentUserService.get().getId(), projectId); - try { + String documentText = ""; + if (documentId != null) { + final Optional documentOptional = documentService.getAsset(documentId, permission); + if (documentOptional.isPresent()) { + final int MAX_CHAR_LIMIT = 9000; - String documentText = ""; - if (documentId != null) { - final Optional documentOptional = documentService.getAsset(documentId, permission); - if (documentOptional.isPresent()) { - final int MAX_CHAR_LIMIT = 9000; - - final DocumentAsset document = documentOptional.get(); - - if (document.getText() != null) { - documentText = document.getText() - .substring(0, Math.min(document.getText().length(), MAX_CHAR_LIMIT)); - } else { - throw new ResponseStatusException( - HttpStatus.BAD_REQUEST, - "Supplied document is still in the extraction process. Please try again later..."); - } - - try { - final Provenance provenancePayload = new Provenance( - ProvenanceRelationType.EXTRACTED_FROM, - modelId, - ProvenanceType.MODEL, - documentId, - ProvenanceType.DOCUMENT); - provenanceService.createProvenance(provenancePayload); - } catch (final Exception e) { - final String error = "Unable to create provenance for profile-model"; - log.error(error, e); - } + final DocumentAsset document = documentOptional.get(); + + if (document.getText() != null) { + documentText = document.getText() + .substring(0, Math.min(document.getText().length(), MAX_CHAR_LIMIT)); + } else { + throw new ResponseStatusException( + HttpStatus.BAD_REQUEST, messages.get("document.extraction.not-done")); + } + + try { + final Provenance provenancePayload = new Provenance( + ProvenanceRelationType.EXTRACTED_FROM, + modelId, + ProvenanceType.MODEL, + documentId, + ProvenanceType.DOCUMENT); + provenanceService.createProvenance(provenancePayload); + } catch (final Exception e) { + final String error = "Unable to create provenance for profile-model"; + log.error(error, e); } } + } - final Model model = modelService.getAsset(modelId, permission).orElseThrow(); + final Model model = modelService.getAsset(modelId, permission).orElseThrow(); - final StringMultipartFile textFile = - new StringMultipartFile(documentText, "document.txt", "application/text"); - final StringMultipartFile codeFile = new StringMultipartFile("", "code.txt", "application/text"); + final StringMultipartFile textFile = new StringMultipartFile(documentText, "document.txt", "application/text"); + final StringMultipartFile codeFile = new StringMultipartFile("", "code.txt", "application/text"); - final ResponseEntity resp; - try { - resp = mitProxy.modelCard(MIT_OPENAI_API_KEY, textFile, codeFile); - } catch (final FeignException e) { - final String error = "Unable to get model card"; - log.error(error, e); - throw new ResponseStatusException( - e.status() < 100 ? HttpStatus.INTERNAL_SERVER_ERROR : HttpStatus.valueOf(e.status()), - error + ": " + e.getMessage()); - } + final ResponseEntity resp; + try { + resp = mitProxy.modelCard(MIT_OPENAI_API_KEY, textFile, codeFile); + } catch (final FeignException e) { + final String error = "Unable to get model card"; + log.error(error, e); - if (!resp.getStatusCode().is2xxSuccessful()) { - throw new ResponseStatusException(resp.getStatusCode(), "Unable to get model card"); - } + throw handleMitFeignException(e); + } - final Card card = mapper.treeToValue(resp.getBody(), Card.class); + if (resp.getStatusCode().is4xxClientError()) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("mit.file.unable-to-read")); + } else if (resp.getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("mit.service-unavailable")); + } else if (!resp.getStatusCode().is2xxSuccessful()) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("mit.internal-error")); + } - if (model.getHeader() == null) { - model.setHeader(new ModelHeader()); - } + final Card card; + try { + card = mapper.treeToValue(resp.getBody(), Card.class); + } catch (final IOException e) { + log.error("Unable to convert response to card", e); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, messages.get("generic.io-error")); + } - if (model.getMetadata() == null) { - model.setMetadata(new ModelMetadata()); - } + if (model.getHeader() == null) { + model.setHeader(new ModelHeader()); + } - model.getHeader().setDescription(card.getDescription()); - model.getMetadata().setCard(card); + if (model.getMetadata() == null) { + model.setMetadata(new ModelMetadata()); + } - return ResponseEntity.ok(modelService.updateAsset(model, permission).orElseThrow()); + model.getHeader().setDescription(card.getDescription()); + model.getMetadata().setCard(card); + final Optional updatedModel; + try { + updatedModel = modelService.updateAsset(model, permission); } catch (final IOException e) { - log.error("Unable to get profile model", e); + log.error("Unable to update model", e); throw new ResponseStatusException( - org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, - "Unable to get profile model: " + e.getMessage()); + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); + } + + if (updatedModel.isEmpty()) { + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, messages.get("model.unable-to-update")); } + + return ResponseEntity.ok(updatedModel.get()); } /** @@ -550,124 +595,130 @@ public ResponseEntity postProfileDataset( final Schema.Permission permission = projectService.checkPermissionCanWrite(currentUserService.get().getId(), projectId); - try { - // Provenance call if a document id is provided - StringMultipartFile documentFile = null; - if (documentId.isPresent()) { + // Provenance call if a document id is provided + StringMultipartFile documentFile = null; + if (documentId.isPresent()) { - final DocumentAsset document = - documentService.getAsset(documentId.get(), permission).orElseThrow(); - documentFile = - new StringMultipartFile(document.getText(), documentId.get() + ".txt", "application/text"); + final DocumentAsset document = + documentService.getAsset(documentId.get(), permission).orElseThrow(); + documentFile = new StringMultipartFile(document.getText(), documentId.get() + ".txt", "application/text"); - try { - final Provenance provenancePayload = new Provenance( - ProvenanceRelationType.EXTRACTED_FROM, - datasetId, - ProvenanceType.DATASET, - documentId.get(), - ProvenanceType.DOCUMENT); - provenanceService.createProvenance(provenancePayload); + try { + final Provenance provenancePayload = new Provenance( + ProvenanceRelationType.EXTRACTED_FROM, + datasetId, + ProvenanceType.DATASET, + documentId.get(), + ProvenanceType.DOCUMENT); + provenanceService.createProvenance(provenancePayload); - } catch (final Exception e) { - final String error = "Unable to create provenance for profile-dataset"; - log.error(error, e); - } - } else { - documentFile = new StringMultipartFile( - "There is no documentation for this dataset", "document.txt", "application/text"); + } catch (final Exception e) { + final String error = "Unable to create provenance for profile-dataset"; + log.error(error, e); } + } else { + documentFile = new StringMultipartFile( + "There is no documentation for this dataset", "document.txt", "application/text"); + } - final Dataset dataset = - datasetService.getAsset(datasetId, permission).orElseThrow(); + final Dataset dataset = datasetService.getAsset(datasetId, permission).orElseThrow(); - if (dataset.getFileNames() == null || dataset.getFileNames().isEmpty()) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "No files found on dataset"); - } - final String filename = dataset.getFileNames().get(0); + if (dataset.getFileNames() == null || dataset.getFileNames().isEmpty()) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, messages.get("dataset.files.not-found")); + } + final String filename = dataset.getFileNames().get(0); + + final String csvContents; + try { + csvContents = datasetService.fetchFileAsString(datasetId, filename).orElseThrow(); + } catch (final IOException e) { + log.error("Unable to fetch file as string", e); + throw new ResponseStatusException( + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); + } - final String csvContents = - datasetService.fetchFileAsString(datasetId, filename).orElseThrow(); + final StringMultipartFile csvFile = new StringMultipartFile(csvContents, filename, "application/csv"); - final StringMultipartFile csvFile = new StringMultipartFile(csvContents, filename, "application/csv"); + final ResponseEntity resp = mitProxy.dataCard(MIT_OPENAI_API_KEY, csvFile, documentFile); - final ResponseEntity resp = mitProxy.dataCard(MIT_OPENAI_API_KEY, csvFile, documentFile); - if (!resp.getStatusCode().is2xxSuccessful()) { - throw new ResponseStatusException(resp.getStatusCode(), "Unable to get data card"); - } + if (resp.getStatusCode().is4xxClientError()) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("mit.file.unable-to-read")); + } else if (resp.getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("mit.service-unavailable")); + } else if (!resp.getStatusCode().is2xxSuccessful()) { + throw new ResponseStatusException(resp.getStatusCode(), messages.get("mit.internal-error")); + } - final JsonNode card = resp.getBody(); - final JsonNode profilingResult = card.get("DATA_PROFILING_RESULT"); + final JsonNode card = resp.getBody(); + final JsonNode profilingResult = card.get("DATA_PROFILING_RESULT"); - final List columns = new ArrayList<>(); - for (final DatasetColumn col : dataset.getColumns()) { + final List columns = new ArrayList<>(); + for (final DatasetColumn col : dataset.getColumns()) { - final JsonNode annotation = profilingResult.get(col.getName()); - if (annotation == null) { - log.warn("No annotations for column: {}", col.getName()); - continue; - } + final JsonNode annotation = profilingResult.get(col.getName()); + if (annotation == null) { + log.warn("No annotations for column: {}", col.getName()); + continue; + } + + final JsonNode dkgGroundings = annotation.get("dkg_groundings"); + if (dkgGroundings == null) { + log.warn("No dkg_groundings for column: {}", col.getName()); + continue; + } - final JsonNode dkgGroundings = annotation.get("dkg_groundings"); - if (dkgGroundings == null) { - log.warn("No dkg_groundings for column: {}", col.getName()); + final Grounding groundings = new Grounding(); + for (final JsonNode g : annotation.get("dkg_groundings")) { + if (g.size() < 2) { + log.warn("Invalid dkg_grounding: {}", g); continue; } - - final Grounding groundings = new Grounding(); - for (final JsonNode g : annotation.get("dkg_groundings")) { - if (g.size() < 2) { - log.warn("Invalid dkg_grounding: {}", g); - continue; - } - if (groundings.getIdentifiers() == null) { - groundings.setIdentifiers(new ArrayList<>()); - } - groundings - .getIdentifiers() - .add(new Identifier(g.get(0).asText(), g.get(1).asText())); + if (groundings.getIdentifiers() == null) { + groundings.setIdentifiers(new ArrayList<>()); } - - // remove groundings from annotation object - ((ObjectNode) annotation).remove("dkg_groundings"); - - final DatasetColumn newCol = new DatasetColumn(); - newCol.setName(col.getName()); - newCol.setDataType(col.getDataType()); - newCol.setFormatStr(col.getFormatStr()); - newCol.setGrounding(groundings); - newCol.setAnnotations(col.getAnnotations()); - newCol.setDescription(annotation.get("description").asText()); - newCol.setMetadata(col.getMetadata()); - newCol.updateMetadata(annotation); - columns.add(newCol); + groundings + .getIdentifiers() + .add(new Identifier(g.get(0).asText(), g.get(1).asText())); } - dataset.setColumns(columns); + // remove groundings from annotation object + ((ObjectNode) annotation).remove("dkg_groundings"); + + final DatasetColumn newCol = new DatasetColumn(); + newCol.setName(col.getName()); + newCol.setDataType(col.getDataType()); + newCol.setFormatStr(col.getFormatStr()); + newCol.setGrounding(groundings); + newCol.setAnnotations(col.getAnnotations()); + newCol.setDescription(annotation.get("description").asText()); + newCol.setMetadata(col.getMetadata()); + newCol.updateMetadata(annotation); + columns.add(newCol); + } - // add card to metadata - if (dataset.getMetadata() == null) { - dataset.setMetadata(mapper.createObjectNode()); - } - ((ObjectNode) dataset.getMetadata()).set("dataCard", card); + dataset.setColumns(columns); - return ResponseEntity.ok( - datasetService.updateAsset(dataset, permission).orElseThrow()); + // add card to metadata + if (dataset.getMetadata() == null) { + dataset.setMetadata(mapper.createObjectNode()); + } + ((ObjectNode) dataset.getMetadata()).set("dataCard", card); - } catch (final FeignException e) { - final String error = "Unable to get profile dataset"; - log.error(error, e); + final Optional updatedDataset; + try { + updatedDataset = datasetService.updateAsset(dataset, permission); + } catch (final IOException e) { + log.error("Unable to update dataset", e); throw new ResponseStatusException( - e.status() < 100 - ? org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR - : HttpStatus.valueOf(e.status()), - error + ": " + e.getMessage()); - } catch (final Exception e) { - final String error = "Unable to get profile dataset"; - log.error(error, e); + HttpStatus.SERVICE_UNAVAILABLE, messages.get("postgres.service-unavailable")); + } + + if (updatedDataset.isEmpty()) { throw new ResponseStatusException( - org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, error + ": " + e.getMessage()); + HttpStatus.INTERNAL_SERVER_ERROR, messages.get("dataset.unable-to-update")); } + + return ResponseEntity.ok(updatedDataset.get()); } @PostMapping("/align-model") @@ -696,8 +747,7 @@ public ResponseEntity alignModel( } catch (final InterruptedException | ExecutionException e) { log.error("Error aligning model with document", e); throw new ResponseStatusException( - org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, - "Error aligning model with document: " + e.getMessage()); + org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, messages.get("skema.error.align-model")); } } @@ -745,4 +795,28 @@ public ResponseEntity pdfExtractions( extractionService.extractPDF(documentId, domain, projectId, permission); return ResponseEntity.accepted().build(); } + + private ResponseStatusException handleSkemaFeignException(final FeignException e) { + final HttpStatus statusCode = HttpStatus.resolve(e.status()); + if (statusCode != null && statusCode.is4xxClientError()) { + return new ResponseStatusException(statusCode, messages.get("skema.bad-equations")); + } else if (statusCode == HttpStatus.SERVICE_UNAVAILABLE) { + return new ResponseStatusException(statusCode, messages.get("skema.service-unavailable")); + } else if (statusCode != null && statusCode.is5xxServerError()) { + return new ResponseStatusException(statusCode, messages.get("skema.internal-error")); + } + return new ResponseStatusException(statusCode, messages.get("generic.unknown")); + } + + private ResponseStatusException handleMitFeignException(final FeignException e) { + final HttpStatus statusCode = HttpStatus.resolve(e.status()); + if (statusCode != null && statusCode.is4xxClientError()) { + return new ResponseStatusException(statusCode, messages.get("mit.file.unable-to-read")); + } else if (statusCode == HttpStatus.SERVICE_UNAVAILABLE) { + return new ResponseStatusException(statusCode, messages.get("mit.service-unavailable")); + } else if (statusCode != null && statusCode.is5xxServerError()) { + return new ResponseStatusException(statusCode, messages.get("skema.internal-error")); + } + return new ResponseStatusException(statusCode, messages.get("generic.unknown")); + } } diff --git a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/utils/rebac/ReBACService.java b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/utils/rebac/ReBACService.java index 48e5e7297c..bd15e25507 100644 --- a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/utils/rebac/ReBACService.java +++ b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/utils/rebac/ReBACService.java @@ -99,7 +99,7 @@ void startup() throws Exception { channel = InProcessChannelBuilder.forName("TestSpiceDB").build(); return; } else { - ManagedChannelBuilder builder = ManagedChannelBuilder.forTarget(SPICEDB_TARGET); + final ManagedChannelBuilder builder = ManagedChannelBuilder.forTarget(SPICEDB_TARGET); if (SPICEDB_LAUNCHMODE.equals("TLS")) { builder.useTransportSecurity(); } else { @@ -122,39 +122,39 @@ void startup() throws Exception { ASKEM_ADMIN_GROUP_ID = createGroup(ASKEM_ADMIN_GROUP_NAME).getId(); } - UsersResource usersResource = keycloak.realm(REALM_NAME).users(); - List users = usersResource.list(); - for (UserRepresentation userRepresentation : users) { + final UsersResource usersResource = keycloak.realm(REALM_NAME).users(); + final List users = usersResource.list(); + for (final UserRepresentation userRepresentation : users) { if (userRepresentation.getEmail() == null || userRepresentation.getEmail().isBlank()) { continue; } - UserResource userResource = usersResource.get(userRepresentation.getId()); - String userId = userRepresentation.getId(); - SchemaObject user = new SchemaObject(Schema.Type.USER, userId); - SchemaObject publicGroup = new SchemaObject(Schema.Type.GROUP, PUBLIC_GROUP_ID); - SchemaObject adminGroup = new SchemaObject(Schema.Type.GROUP, ASKEM_ADMIN_GROUP_ID); + final UserResource userResource = usersResource.get(userRepresentation.getId()); + final String userId = userRepresentation.getId(); + final SchemaObject user = new SchemaObject(Schema.Type.USER, userId); + final SchemaObject publicGroup = new SchemaObject(Schema.Type.GROUP, PUBLIC_GROUP_ID); + final SchemaObject adminGroup = new SchemaObject(Schema.Type.GROUP, ASKEM_ADMIN_GROUP_ID); - for (RoleRepresentation roleRepresentation : + for (final RoleRepresentation roleRepresentation : userResource.roles().getAll().getRealmMappings()) { if (roleRepresentation.getDescription().isBlank()) { switch (roleRepresentation.getName()) { case "user": try { createRelationship(user, publicGroup, Schema.Relationship.MEMBER); - } catch (RelationshipAlreadyExistsException e) { + } catch (final RelationshipAlreadyExistsException e) { log.error("Failed to add user {} to Public Group", userId, e); } break; case "admin": try { createRelationship(user, publicGroup, Schema.Relationship.ADMIN); - } catch (RelationshipAlreadyExistsException e) { + } catch (final RelationshipAlreadyExistsException e) { log.error("Failed to add admin {} to Public Group", userId, e); } try { createRelationship(user, adminGroup, Schema.Relationship.ADMIN); - } catch (RelationshipAlreadyExistsException e) { + } catch (final RelationshipAlreadyExistsException e) { log.error("Failed to add admin {} to Admin Group", userId, e); } break; @@ -167,23 +167,24 @@ void startup() throws Exception { ASKEM_ADMIN_GROUP_ID = getGroupId(ASKEM_ADMIN_GROUP_NAME); // Ensure ASKEM_ADMIN_GROUP can write to all Projects - SchemaObject askemAdminGroup = new SchemaObject(Schema.Type.GROUP, ASKEM_ADMIN_GROUP_ID); - ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); - List projectIds = rebac.lookupResources(Schema.Type.PROJECT, getCurrentConsistency()); - for (UUID projectId : projectIds) { - SchemaObject project = new SchemaObject(Schema.Type.PROJECT, projectId.toString()); + final SchemaObject askemAdminGroup = new SchemaObject(Schema.Type.GROUP, ASKEM_ADMIN_GROUP_ID); + final ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); + final List projectIds = rebac.lookupResources(Schema.Type.PROJECT, getCurrentConsistency()); + for (final UUID projectId : projectIds) { + final SchemaObject project = new SchemaObject(Schema.Type.PROJECT, projectId.toString()); try { createRelationship(askemAdminGroup, project, Schema.Relationship.WRITER); - } catch (RelationshipAlreadyExistsException ignore) { + } catch (final RelationshipAlreadyExistsException ignore) { } } } API_SERVICE_USER_ID = getUserId(API_SERVICE_USER_NAME); } - private String getUserId(String name) { - List users = keycloak.realm(REALM_NAME).users().search(name); - for (UserRepresentation user : users) { + private String getUserId(final String name) { + final List users = + keycloak.realm(REALM_NAME).users().search(name); + for (final UserRepresentation user : users) { if (user.getUsername().equals(API_SERVICE_USER_NAME)) { return user.getId(); } @@ -191,10 +192,10 @@ private String getUserId(String name) { throw new RuntimeException("Api service user account does not exist"); } - private String getGroupId(String name) { - List groups = + private String getGroupId(final String name) { + final List groups = keycloak.realm(REALM_NAME).groups().groups(name, true, 0, Integer.MAX_VALUE, true); - for (GroupRepresentation group : groups) { + for (final GroupRepresentation group : groups) { if (group.getPath().equals("/" + name)) { return group.getId(); } @@ -202,20 +203,21 @@ private String getGroupId(String name) { return null; } - private Response createGroupMaybeParent(String parentId, GroupRepresentation group) { + private Response createGroupMaybeParent(final String parentId, final GroupRepresentation group) { if (parentId == null) { return keycloak.realm(REALM_NAME).groups().add(group); } else { - GroupResource parentGroup = keycloak.realm(REALM_NAME).groups().group(parentId); + final GroupResource parentGroup = + keycloak.realm(REALM_NAME).groups().group(parentId); return parentGroup.subGroup(group); } } - private PermissionGroup createGroup(String parentId, String name) { - GroupRepresentation groupRepresentation = new GroupRepresentation(); + private PermissionGroup createGroup(final String parentId, final String name) { + final GroupRepresentation groupRepresentation = new GroupRepresentation(); groupRepresentation.setName(name); - Response response = createGroupMaybeParent(parentId, groupRepresentation); + final Response response = createGroupMaybeParent(parentId, groupRepresentation); switch (response.getStatus()) { case 201: return new PermissionGroup(CreatedResponseUtil.getCreatedId(response), name); @@ -228,14 +230,14 @@ private PermissionGroup createGroup(String parentId, String name) { } } - public PermissionGroup createGroup(String name) { + public PermissionGroup createGroup(final String name) { return this.createGroup(null, name); } - public PermissionUser getUser(String id) { - UsersResource usersResource = keycloak.realm(REALM_NAME).users(); - UserResource userResource = usersResource.get(id); - UserRepresentation userRepresentation = userResource.toRepresentation(); + public PermissionUser getUser(final String id) { + final UsersResource usersResource = keycloak.realm(REALM_NAME).users(); + final UserResource userResource = usersResource.get(id); + final UserRepresentation userRepresentation = userResource.toRepresentation(); return new PermissionUser( userRepresentation.getId(), userRepresentation.getFirstName(), @@ -244,22 +246,22 @@ public PermissionUser getUser(String id) { } public List getUsers() { - List response = new ArrayList<>(); - UsersResource usersResource = keycloak.realm(REALM_NAME).users(); - Integer maxUsers = usersResource.count(); - List users = usersResource.list(0, maxUsers + 1); - for (UserRepresentation userRepresentation : users) { + final List response = new ArrayList<>(); + final UsersResource usersResource = keycloak.realm(REALM_NAME).users(); + final Integer maxUsers = usersResource.count(); + final List users = usersResource.list(0, maxUsers + 1); + for (final UserRepresentation userRepresentation : users) { if (userRepresentation.getEmail() == null || userRepresentation.getEmail().isBlank()) { continue; } - UserResource userResource = usersResource.get(userRepresentation.getId()); + final UserResource userResource = usersResource.get(userRepresentation.getId()); - List roles = new ArrayList<>(); - for (RoleRepresentation roleRepresentation : + final List roles = new ArrayList<>(); + for (final RoleRepresentation roleRepresentation : userResource.roles().getAll().getRealmMappings()) { if (roleRepresentation.getDescription().isBlank()) { - PermissionRole role = new PermissionRole( + final PermissionRole role = new PermissionRole( roleRepresentation.getId(), roleRepresentation.getName() // no users are acquired (to avoid circular references etc) ); @@ -267,7 +269,7 @@ public List getUsers() { } } - PermissionUser user = new PermissionUser( + final PermissionUser user = new PermissionUser( userRepresentation.getId(), userRepresentation.getFirstName(), userRepresentation.getLastName(), @@ -279,16 +281,16 @@ public List getUsers() { } public List getRoles() { - List response = new ArrayList<>(); + final List response = new ArrayList<>(); - RolesResource rolesResource = keycloak.realm(REALM_NAME).roles(); - for (RoleRepresentation roleRepresentation : rolesResource.list()) { + final RolesResource rolesResource = keycloak.realm(REALM_NAME).roles(); + for (final RoleRepresentation roleRepresentation : rolesResource.list()) { if (roleRepresentation.getDescription().isBlank()) { - RoleResource roleResource = rolesResource.get(roleRepresentation.getName()); - List users = new ArrayList<>(); - for (UserRepresentation userRepresentation : roleResource.getRoleUserMembers()) { + final RoleResource roleResource = rolesResource.get(roleRepresentation.getName()); + final List users = new ArrayList<>(); + for (final UserRepresentation userRepresentation : roleResource.getRoleUserMembers()) { if (userRepresentation.getEmail() != null) { - PermissionUser user = new PermissionUser( + final PermissionUser user = new PermissionUser( userRepresentation.getId(), userRepresentation.getFirstName(), userRepresentation.getLastName(), @@ -299,7 +301,7 @@ public List getRoles() { } } - PermissionRole role = + final PermissionRole role = new PermissionRole(roleRepresentation.getId(), roleRepresentation.getName(), users); response.add(role); } @@ -309,21 +311,23 @@ public List getRoles() { } public List getGroups() { - List response = new ArrayList<>(); + final List response = new ArrayList<>(); - List groups = keycloak.realm(REALM_NAME).groups().groups(); - for (GroupRepresentation groupRepresentation : groups) { - PermissionGroup group = new PermissionGroup(groupRepresentation.getId(), groupRepresentation.getName()); + final List groups = + keycloak.realm(REALM_NAME).groups().groups(); + for (final GroupRepresentation groupRepresentation : groups) { + final PermissionGroup group = + new PermissionGroup(groupRepresentation.getId(), groupRepresentation.getName()); response.add(group); } return response; } - public PermissionGroup getGroup(String id) { - GroupResource groupResource = keycloak.realm(REALM_NAME).groups().group(id); - GroupRepresentation groupRepresentation = groupResource.toRepresentation(); - PermissionGroup permissionGroup = + public PermissionGroup getGroup(final String id) { + final GroupResource groupResource = keycloak.realm(REALM_NAME).groups().group(id); + final GroupRepresentation groupRepresentation = groupResource.toRepresentation(); + final PermissionGroup permissionGroup = new PermissionGroup(groupRepresentation.getId(), groupRepresentation.getName()); return permissionGroup; @@ -338,33 +342,36 @@ public PermissionGroup getGroup(String id) { * @return true if resource grants permission for user, otherwise false * @throws Exception some sort of ReBAC error, most likely SpiceDB is unavailable */ - public boolean can(SchemaObject who, Schema.Permission permission, SchemaObject what) throws Exception { - ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); + public boolean can(final SchemaObject who, final Schema.Permission permission, final SchemaObject what) + throws Exception { + final ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); if (SPICEDB_LAUNCHMODE.equals("TEST")) { return true; } return rebac.checkPermission(who, permission, what, getCurrentConsistency()); } - public boolean isMemberOf(SchemaObject who, SchemaObject what) throws Exception { - ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); + public boolean isMemberOf(final SchemaObject who, final SchemaObject what) throws Exception { + final ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); return rebac.checkPermission(who, Schema.Permission.MEMBERSHIP, what, getCurrentConsistency()); } - public boolean isCreator(SchemaObject who, SchemaObject what) throws Exception { - ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); + public boolean isCreator(final SchemaObject who, final SchemaObject what) throws Exception { + final ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); return rebac.hasRelationship(who, Schema.Relationship.CREATOR, what, getCurrentConsistency()); } - public void createRelationship(SchemaObject who, SchemaObject what, Schema.Relationship relationship) + public void createRelationship( + final SchemaObject who, final SchemaObject what, final Schema.Relationship relationship) throws Exception, RelationshipAlreadyExistsException { - ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); + final ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); CURRENT_ZED_TOKEN = rebac.createRelationship(who, relationship, what); } - public void removeRelationship(SchemaObject who, SchemaObject what, Schema.Relationship relationship) + public void removeRelationship( + final SchemaObject who, final SchemaObject what, final Schema.Relationship relationship) throws Exception, RelationshipAlreadyExistsException { - ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); + final ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); CURRENT_ZED_TOKEN = rebac.removeRelationship(who, relationship, what); } @@ -372,30 +379,30 @@ private Consistency getCurrentConsistency() { if (CURRENT_ZED_TOKEN == null) { return Consistency.newBuilder().setFullyConsistent(true).build(); } - Core.ZedToken zedToken = + final Core.ZedToken zedToken = Core.ZedToken.newBuilder().setToken(CURRENT_ZED_TOKEN).build(); return Consistency.newBuilder().setAtLeastAsFresh(zedToken).build(); } - public List getRelationships(SchemaObject what) throws Exception { - ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); + public List getRelationships(final SchemaObject what) throws Exception { + final ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); return rebac.getRelationship(what, getCurrentConsistency()); } - public ResponseEntity deleteRoleFromUser(String roleName, String userId) { - UsersResource usersResource = keycloak.realm(REALM_NAME).users(); - UserResource userResource = usersResource.get(userId); + public ResponseEntity deleteRoleFromUser(final String roleName, final String userId) { + final UsersResource usersResource = keycloak.realm(REALM_NAME).users(); + final UserResource userResource = usersResource.get(userId); try { // test to see if user was found userResource.toRepresentation(); - } catch (Exception ignore) { + } catch (final Exception ignore) { log.error("There is no user with id {}", userId); return ResponseEntity.notFound().build(); } RoleRepresentation roleToRemove = null; - RolesResource rolesResource = keycloak.realm(REALM_NAME).roles(); - for (RoleRepresentation roleRepresentation : rolesResource.list()) { + final RolesResource rolesResource = keycloak.realm(REALM_NAME).roles(); + for (final RoleRepresentation roleRepresentation : rolesResource.list()) { // RoleResource roleResource = rolesResource.get(roleRepresentation.getName()); if (roleRepresentation.getName().equals(roleName)) { roleToRemove = roleRepresentation; @@ -407,39 +414,39 @@ public ResponseEntity deleteRoleFromUser(String roleName, String userId) { return ResponseEntity.notFound().build(); } - String resourceUrl = composeResourceUrl( + final String resourceUrl = composeResourceUrl( config.getKeycloak().getUrl() + "/admin/", REALM_NAME, "users/" + userId + "/role-mappings/realm"); - List roles = new ArrayList<>(); + final List roles = new ArrayList<>(); roles.add(roleToRemove); try { doDeleteJSON(resourceUrl, getKeycloakBearerToken(), roles); return ResponseEntity.ok().build(); - } catch (Exception e) { + } catch (final Exception e) { log.error(e.getMessage()); return ResponseEntity.internalServerError().build(); } } - public ResponseEntity addRoleToUser(String roleName, String userId) { - UsersResource usersResource = keycloak.realm(REALM_NAME).users(); - UserResource userResource = usersResource.get(userId); + public ResponseEntity addRoleToUser(final String roleName, final String userId) { + final UsersResource usersResource = keycloak.realm(REALM_NAME).users(); + final UserResource userResource = usersResource.get(userId); try { // test to see if user was found userResource.toRepresentation(); - } catch (Exception ignore) { + } catch (final Exception ignore) { log.error("There is no user with id {}", userId); return ResponseEntity.notFound().build(); } RoleRepresentation roleToAdd = null; - RolesResource rolesResource = keycloak.realm(REALM_NAME).roles(); - for (RoleRepresentation roleRepresentation : rolesResource.list()) { - RoleResource roleResource = rolesResource.get(roleRepresentation.getName()); + final RolesResource rolesResource = keycloak.realm(REALM_NAME).roles(); + for (final RoleRepresentation roleRepresentation : rolesResource.list()) { + final RoleResource roleResource = rolesResource.get(roleRepresentation.getName()); if (roleRepresentation.getName().equals(roleName)) { roleToAdd = roleRepresentation; - for (UserRepresentation user : roleResource.getRoleUserMembers()) { + for (final UserRepresentation user : roleResource.getRoleUserMembers()) { if (user.getId().equals(userId)) { log.debug("Add Role To User: already belongs"); return ResponseEntity.status(HttpStatusCode.valueOf(304)) @@ -454,29 +461,28 @@ public ResponseEntity addRoleToUser(String roleName, String userId) { return ResponseEntity.notFound().build(); } - String resourceUrl = composeResourceUrl( + final String resourceUrl = composeResourceUrl( config.getKeycloak().getUrl() + "/admin/", REALM_NAME, "users/" + userId + "/role-mappings/realm"); - List roles = new ArrayList<>(); + final List roles = new ArrayList<>(); roles.add(roleToAdd); try { doPostJSON(resourceUrl, getKeycloakBearerToken(), roles); return ResponseEntity.ok().build(); - } catch (Exception e) { + } catch (final Exception e) { log.error(e.getMessage()); return ResponseEntity.internalServerError().build(); } } - public List lookupResources(SchemaObject who, Schema.Permission permission, Schema.Type type) - throws Exception { - ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); + public List lookupResources( + final SchemaObject who, final Schema.Permission permission, final Schema.Type type) throws Exception { + final ReBACFunctions rebac = new ReBACFunctions(channel, spiceDbBearerToken); return rebac.lookupResources(type, permission, who, getCurrentConsistency()); } - public boolean isServiceUser(String id) { - if (API_SERVICE_USER_ID != null && API_SERVICE_USER_ID.equals(id)) return true; - return false; + public static boolean isServiceUser(final String id) { + return API_SERVICE_USER_ID != null && API_SERVICE_USER_ID.equals(id); } } diff --git a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/utils/rebac/askem/RebacUser.java b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/utils/rebac/askem/RebacUser.java index 2c5dd47cf2..1fd62c8876 100644 --- a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/utils/rebac/askem/RebacUser.java +++ b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/utils/rebac/askem/RebacUser.java @@ -9,44 +9,45 @@ import software.uncharted.terarium.hmiserver.utils.rebac.SchemaObject; public class RebacUser extends RebacObject { - private ReBACService reBACService; + private final ReBACService reBACService; - private boolean serviceUser; + private final boolean serviceUser; - public RebacUser(String id, ReBACService reBACService) { + public RebacUser(final String id, final ReBACService reBACService) { super(id); this.reBACService = reBACService; - serviceUser = reBACService.isServiceUser(id); + serviceUser = ReBACService.isServiceUser(id); } + @Override public SchemaObject getSchemaObject() { return new SchemaObject(Schema.Type.USER, getId()); } - public boolean can(RebacObject rebacObject, Schema.Permission permission) throws Exception { + public boolean can(final RebacObject rebacObject, final Schema.Permission permission) throws Exception { if (serviceUser) return true; if (rebacObject.getId().isEmpty()) return false; return reBACService.can(getSchemaObject(), permission, rebacObject.getSchemaObject()); } - public boolean isMemberOf(RebacGroup rebacGroup) throws Exception { + public boolean isMemberOf(final RebacGroup rebacGroup) throws Exception { return reBACService.isMemberOf(getSchemaObject(), rebacGroup.getSchemaObject()); } - public void createCreatorRelationship(RebacObject rebacObject) + public void createCreatorRelationship(final RebacObject rebacObject) throws Exception, RelationshipAlreadyExistsException { reBACService.createRelationship(getSchemaObject(), rebacObject.getSchemaObject(), Schema.Relationship.CREATOR); } - public PermissionGroup createGroup(String name) throws Exception, RelationshipAlreadyExistsException { - PermissionGroup group = reBACService.createGroup(name); + public PermissionGroup createGroup(final String name) throws Exception, RelationshipAlreadyExistsException { + final PermissionGroup group = reBACService.createGroup(name); reBACService.createRelationship( getSchemaObject(), new SchemaObject(Schema.Type.GROUP, group.getId()), Schema.Relationship.CREATOR); return group; } - public String getPermissionFor(RebacProject rebacProject) throws Exception { + public String getPermissionFor(final RebacProject rebacProject) throws Exception { if (reBACService.isCreator(getSchemaObject(), rebacProject.getSchemaObject())) { return Schema.Relationship.CREATOR.toString(); } else if (can(rebacProject, Schema.Permission.ADMINISTRATE)) { diff --git a/packages/server/src/main/resources/application-ide.properties b/packages/server/src/main/resources/application-ide.properties deleted file mode 100644 index 915cfe87e8..0000000000 --- a/packages/server/src/main/resources/application-ide.properties +++ /dev/null @@ -1,33 +0,0 @@ -######################################################################################################################## -# Database configuration -######################################################################################################################## -spring.datasource.url=jdbc:postgresql://localhost:5430/terarium - -######################################################################################################################## -# Elasticsearch configuration -######################################################################################################################## -terarium.elasticsearch.url=http://localhost:9200 - -######################################################################################################################## -# aws credentials configuration -######################################################################################################################## -aws-url=http://localhost:9000 - -######################################################################################################################## -# neo4j configuration -######################################################################################################################## -spring.neo4j.uri=bolt://localhost:7687 -######################################################################################################################## -# RabbitMQ exchange -######################################################################################################################## -spring.rabbitmq.addresses=amqp://localhost:5672 - -######################################################################################################################## -# Redis configuration -######################################################################################################################## -spring.data.redis.url=redis://localhost:6379 - -######################################################################################################################## -# Server configuration -######################################################################################################################## -terarium.swagger.server-url=http://localhost:3000 diff --git a/packages/server/src/main/resources/application-local-keycloak.properties b/packages/server/src/main/resources/application-local-keycloak.properties index a8788c6407..af21e2a414 100644 --- a/packages/server/src/main/resources/application-local-keycloak.properties +++ b/packages/server/src/main/resources/application-local-keycloak.properties @@ -1,3 +1,26 @@ +######################################################################################################################## +# Database configuration +######################################################################################################################## + +######################################################################################################################## +# Elasticsearch configuration +######################################################################################################################## + +######################################################################################################################## +# Flyway configuration +######################################################################################################################## + +######################################################################################################################## +# Request Logging +######################################################################################################################## + +######################################################################################################################## +# Caching +######################################################################################################################## + +######################################################################################################################## +# Keycloak configuration +######################################################################################################################## terarium.keycloak.url=http://localhost:8081 terarium.keycloak.realm=Terarium terarium.keycloak.client-id=app @@ -5,3 +28,63 @@ terarium.keycloak.admin-realm=master terarium.keycloak.admin-client-id=admin-cli terarium.keycloak.admin-username=admin terarium.keycloak.admin-password=admin123 + +######################################################################################################################## +# Application configuration +######################################################################################################################## + +######################################################################################################################## +# Server configuration +######################################################################################################################## + +######################################################################################################################## +# AWS credentials configuration +######################################################################################################################## + +######################################################################################################################## +# Microservice configuration +######################################################################################################################## + +######################################################################################################################## +# Beaker configuration +######################################################################################################################## + +######################################################################################################################## +# ReBAC configuration +######################################################################################################################## + +######################################################################################################################## +# RabbitMQ configuration +######################################################################################################################## + +######################################################################################################################## +# Neo4j configuration +######################################################################################################################## + +######################################################################################################################## +# Redis configuration +######################################################################################################################## + +######################################################################################################################## +# TaskRunner configuration +######################################################################################################################## + +######################################################################################################################## +# Logging +######################################################################################################################## + +######################################################################################################################## +# Cache Logging +######################################################################################################################## + +######################################################################################################################## +# Hibernate Logging +######################################################################################################################## + +######################################################################################################################## +# Hypersistence configuration +######################################################################################################################## + +######################################################################################################################## +# Feign client configuration +######################################################################################################################## diff --git a/packages/server/src/main/resources/application-local.properties b/packages/server/src/main/resources/application-local.properties index 182bacd6d3..b980721d09 100644 --- a/packages/server/src/main/resources/application-local.properties +++ b/packages/server/src/main/resources/application-local.properties @@ -15,9 +15,41 @@ terarium.elasticsearch.url=http://localhost:9200 terarium.elasticsearch.auth-enabled=false ######################################################################################################################## -# Microservice configurations +# Flyway configuration +######################################################################################################################## + +######################################################################################################################## +# Request Logging +######################################################################################################################## + +######################################################################################################################## +# Caching +######################################################################################################################## + +######################################################################################################################## +# Keycloak configuration +######################################################################################################################## + +######################################################################################################################## +# Application configuration +######################################################################################################################## + +######################################################################################################################## +# Server configuration +######################################################################################################################## +terarium.swagger.server-url=http://localhost:3000 + +######################################################################################################################## +# AWS credentials configuration +######################################################################################################################## +aws-access-key-id=admin +aws-secret-access-key=admin123 +aws-url=http://minio:9000 +terarium.file-storage-s3-bucket-name=askem-local-storage + +######################################################################################################################## +# Microservice configuration ######################################################################################################################## -terarium.dataservice.url=http://localhost:3020 simulation-service.url=http://localhost:3030 ciemss-service.url=http://localhost:3040 @@ -29,42 +61,51 @@ tgpt.app.url=http://localhost:8080/beaker/ tgpt.ws.url=ws://localhost:8080/beaker_ws/ ######################################################################################################################## -# ReBAC Configuration +# ReBAC configuration ######################################################################################################################## spicedb.launchmode=PLAINTEXT spicedb.shared-key=dev spicedb.target=localhost:50051 ######################################################################################################################## -# aws credentials configuration +# RabbitMQ configuration ######################################################################################################################## -aws-access-key-id=admin -aws-secret-access-key=admin123 -aws-url=http://minio:9000 -terarium.file-storage-s3-bucket-name=askem-local-storage +spring.rabbitmq.addresses=amqp://localhost:5672 +terarium.mq-username=terarium +terarium.mq-password=terarium123 ######################################################################################################################## -# neo4j configuration +# Neo4j configuration ######################################################################################################################## spring.neo4j.uri=bolt://localhost:7687 -spring.neo4j.authentication.username=neo4j -spring.neo4j.authentication.password=password +neo4j-username=neo4j +neo4j-password=password ######################################################################################################################## -# RabbitMQ exchange +# Redis configuration ######################################################################################################################## -terarium.mq-username=terarium -terarium.mq-password=terarium123 -spring.rabbitmq.addresses=amqp://localhost:5672 -spring.rabbitmq.username=${terarium.mq-username} -spring.rabbitmq.password=${terarium.mq-password} +spring.data.redis.url=redis://localhost:6379 ######################################################################################################################## -# Redis configuration +# TaskRunner configuration ######################################################################################################################## -spring.data.redis.url=redis://localhost:6379 ######################################################################################################################## -# Server configuration +# Logging +######################################################################################################################## + +######################################################################################################################## +# Cache Logging +######################################################################################################################## + +######################################################################################################################## +# Hibernate Logging +######################################################################################################################## + +######################################################################################################################## +# Hypersistence configuration +######################################################################################################################## + +######################################################################################################################## +# Feign client configuration ######################################################################################################################## -terarium.swagger.server-url=http://localhost:3000 diff --git a/packages/server/src/main/resources/application-remote.properties b/packages/server/src/main/resources/application-remote.properties deleted file mode 100644 index 43030dffdb..0000000000 --- a/packages/server/src/main/resources/application-remote.properties +++ /dev/null @@ -1,8 +0,0 @@ -######################################################################################################################## -# Elasticsearch configuration -######################################################################################################################## -terarium.elasticsearch.username=${es-username} -terarium.elasticsearch.password=${es-password} -terarium.elasticsearch.auth_enabled=true - -aws-url= diff --git a/packages/server/src/main/resources/application-secrets.properties.encrypted b/packages/server/src/main/resources/application-secrets.properties.encrypted index 54c14e5cfc..5ad0e89e25 100644 --- a/packages/server/src/main/resources/application-secrets.properties.encrypted +++ b/packages/server/src/main/resources/application-secrets.properties.encrypted @@ -1,64 +1,57 @@ $ANSIBLE_VAULT;1.1;AES256 -32323236306366376563356461393364303535623431376632396633376336343931643066373237 -3038333065356131633336633632333432666165353833320a366563633162616362613062313335 -62363263336431353461363965663932663234316234363563303237626430323033356266643736 -6466643532303537300a623761633031643636633864366431373833396561336439346538323832 -31346664653562336266636637333938643730373561663832626165373139393937303564663133 -61366435303162396237326232633461383961313635343165666238313336333365623562653438 -39656565643331353339613163616364323464373636316138653935313363623466326632623131 -63623730316337363237623961663636613737303931636461316562303232353562333736323334 -30326430663637386661623432623061356637646332616237666232633265343263633061643764 -34613137636431656432623561663439616331303266306162373334356164323566623836643530 -34623831343137366561373838663035376636323764366436353937623437633234636262636663 -33313836353531383034363266353239313338396432663434666230656335313266663530353030 -34343962356637363964356235363538306132376230323164333437363637353261383266616561 -36333137613264353534303835336135336430393366303461646664636264333065633665373130 -38303265383337613033373534373865633036666634643438623937343632346237626638363164 -39393537643336623531653861613832636361656563303435626634353133626537643434383130 -65633865666439336233313131623563623130366236623033646632323166626339313966373131 -61376632336563303734363564613864333936616539623836646664616536346165306339353436 -65366231346533663439636462353834393532363662346330666233643635323138363238313538 -35396266383738373630343039386636636636663637333537666333663761356537333233386432 -61383333323831656638373237633937663638386563343761616532663737636363633964316435 -30306236393662656134623963326333326337643234333034393432623431336237303430336137 -61333661626564343931643131303863316338376361356337366531313535306165366462383038 -35623066366465353562616238363236303034613565643036633139663066663732313466363364 -63303831633066623862666536376130633665383131393230333061383035333139313733366563 -61643966353461356130616438633364306432323131393332383933303839393361663761663563 -32633962393637373665656533666565623735343038333136306539656263346564333533653766 -30373636306231663737303539363566643265316438396464666161393332393961663162666139 -31653765323264623664326637613864383731663661383334666364353264306161316533346330 -33646561616436376230343237646237373334616436643538336233306430613161353633303232 -62326234633534366462336563613963346134633465373962616466376466306234336236306537 -66303432326239343466333162616433613136633138343865353037633831343634333539623236 -31363939386361393335633335636161363762336431383361663831303736353961363632313431 -38643864643166323936653230386637373238353563626161613562323938366165636233386461 -36646161343161383937353961643639333965306262313633363934393439376532656666613734 -65393534393963353134623535633639663961653564346637323163303335343436323333306562 -64386366663164333466376263393961373332393633663939356536316335386665363665616163 -34343063316263616262313265643461386461316666663030363734656161646162393765373031 -65376134316661303965393863316533613233616430396639343930666266343639656333306331 -38373363333930316431373636393535373436313430313233316331623638393031356165303336 -61636636356631396639326435356532343863653233326564643936663162636364333265316366 -65613434393335396136383762356665633637376163613062343836643330393133613663616365 -30663262643634303532663035356434636665373436666537316633663230313830663635386364 -65316165653330626265653333343866356639303939323839323861656430313963383865373365 -32366433313665336136633361636264643961353062653238353834383730663062363338643837 -30336433623164353838653561656133313831653932383363663561386561373732626130616464 -39303861623736653464623361383963356133613531316433303764306265663762343939336664 -30633437343938356631373632366638333036353135316132346439343237666638613534383634 -36663564363265353834376562663333626266383435616637656434383933303839663233353234 -38393030326431376535383661613632623561393239373563633963353365623931323934316363 -36643263323831393937343731623061616463363331646561303766326365356335353437623934 -31646335343666386636666535373130363036633565363766363865336138653532353164623739 -36663431303439653133626237326337386364613131343166626164623439306137646662393930 -30353931343863613464313364343938323831313034333762373237393238356364363733343435 -65636131636631616563303738363038303832386330393266363362646436376461303431353437 -61356433373237663434333061653866613963653131636264633866633863616330663835323665 -30313638626134613232633034356133386333303330656663313338616464646566363961323832 -66663236393432393639613239336264306265666433326364646333323861306565336234303738 -39373664313438376538613466346431396462343031373133663862653435363435333862626263 -30616631363565623865613536353861323039326139306137386438636634666538356236646265 -64636362333464386237313932666232396536336464373833383464383336636564336666303434 -63613933333930333962646662656534306262663539393066393065636464303664396339383434 -336237613939373036313564616562663565 +31346436326463326365613231316431396135646331666331653638653063643338393262363031 +3365376333613264643764306132376136626438396265610a303037633262313630363533323635 +35353532363436353065636365323038306330313638383236636461646538666437343734656334 +6433336331393636630a356164643833306636643866303434383735393635396265316336316664 +33326163346164343566653835303430663834326562636535393234313564333165323139363633 +62363939386265363862356136633139326362353365343366313939396438633863343361353933 +34356430333731633638376466653263326662353561646633303933613032613638303530643237 +64656536616564326338636261363338383930636538636638653365346663623138623461376562 +34626463363031346532303831633162633033393033343066313261373836363938353334663636 +66663961396237623165663839343030346332656637303665656330626431636539653661626433 +31623231386261623330663433613662306162373533613338616338363338383061366434656636 +34336431373836393938396133356363313231633231376266333338383638326134323161616431 +33643438626333313162643939393162393363313965616565356331323734313736663663363038 +38353262633238623764646332313361316331373164633463356465613134303065353733356132 +39663036353931303737306337316434326335323139386662306262646132633636643231333764 +65623839313464373834653065353530393166623864343837356465393932386637656631333434 +33353666626664313530353436393635353733373832653838393961333061666639653338656264 +38626233323662663431363464323231663762363062326466626337393838346166623535333632 +32386636636461633962333862383139373063643631656162626166386431613139343666626239 +63326135363236383561396235363832656536313731306331623763333831333364376337326130 +64646539653939643939623931653161393561643765663066633432386165376234623864313034 +65656437383766356433383431643435643533633738383431623564633331356362316161363935 +37303364353935656639313331663663343961636664633663656433653834313830313339383761 +36653538376433363030363266616433303838383133323361353266386137646165393362343063 +30643735306363613237383537356136306364376430623034386364303633323361333133646261 +31346562303465373861303432396139343963323862633161343261666266386264313366336262 +62333338303761323037393965313066333335393038633861393063363663386139353162646662 +39623833633332663062306466306232313564353430386636623763633937383237373061663666 +32666335313465626137363530636637316336623032313061623437343365663466663361636530 +36633363306530313765643334343534656137313636333630393234666339646635353965613339 +66343362373530666637333861346263373236376234316639386639616330656464633861373262 +62636637373962363736393964356365323062366239646534313030663966316364313564323139 +33336537373234356162663439356432313731326131626465353231393237616666666561656631 +61393562616461366439303832363363386336333930336138353062646636353166356465313437 +63353966643861346364356234336264306366633036333061303131303664386563316563313961 +32306336373938303835666562316535333131663436323231656266623431613665343262396331 +37373261623763343562386136326438326264666261633139623330333837653466613332626536 +31666530643033363365613935356664653838666162363035613939636232393164306137633265 +37313737643838376431326639656438343563323430393565643034616135656239353932393465 +36353932383566373663383065366133316565353037643764333265303165303337656436306631 +34323934626632636539363130373136353630653139383736323566383061613731323166636366 +35343834646261366337353232626466653735306265366336613834383865373135623133613162 +33326465623365643537306330306366303532313966643035376162356434643137653039306663 +33373762353933346263323464396535636336333731393164666336353630623131363535626433 +38663364343164643639643663666439386266306631356432663962356532343663303064306430 +39653734623832383366373163643065323366666239306434633939353165613633306234323263 +30653733343164643138626635343861373330613030303835623565396130363463376433363739 +38616564646462636465353238656530666364643036373738373330363265303665656537363633 +35646136663334633964643233656633353733313038653735336339313531626462383864636562 +35326466393964363339353635616338383061323461303133323734363663326533663964353031 +64366363336131623136653363646463626135373438623939373837393764313835613639613763 +38626132346530653761623561613133383761366436643933656265306132303266306663366531 +35343134316537666535353935646332313236373431313061363162626136666238623135343465 +66313032376437653266663632633938613130363733316261656663663032623461383536313238 +37373265356639666639313039653839636435316434633134376531393732353661376363616339 +39376431333036616238 diff --git a/packages/server/src/main/resources/application-beta.properties b/packages/server/src/main/resources/application-staging-keycloak.properties similarity index 57% rename from packages/server/src/main/resources/application-beta.properties rename to packages/server/src/main/resources/application-staging-keycloak.properties index 539c8af2c9..b820be8bd5 100644 --- a/packages/server/src/main/resources/application-beta.properties +++ b/packages/server/src/main/resources/application-staging-keycloak.properties @@ -1,86 +1,85 @@ ######################################################################################################################## # Database configuration ######################################################################################################################## -spring.datasource.url=jdbc:postgresql://postgres.beta.terarium.ai:5432/terarium -spring.datasource.password=${terarium.db.password} -spring.datasource.username=${terarium.db.username} -spring.datasource.initialize=false -spring.jpa.hibernate.ddl-auto=none ######################################################################################################################## # Elasticsearch configuration ######################################################################################################################## -terarium.elasticsearch.url=https://elasticsearch.beta.terarium.ai:443 -terarium.elasticsearch.auth-enabled=true -terarium.elasticsearch.username=${es-username} -terarium.elasticsearch.password=${es-password} ######################################################################################################################## -# neo4j configuration +# Flyway configuration ######################################################################################################################## -management.health.neo4j.enabled=false ######################################################################################################################## -# Flyway configuration +# Request Logging ######################################################################################################################## -spring.flyway.baseline-on-migrate=false ######################################################################################################################## -# Keycloak Configuration +# Caching ######################################################################################################################## -terarium.keycloak.url=https://keycloak.beta.terarium.ai ######################################################################################################################## -# application configuration +# Keycloak configuration +######################################################################################################################## +terarium.keycloak.url=https://keycloak.staging.terarium.ai +terarium.keycloak.realm=Uncharted + +######################################################################################################################## +# Application configuration ######################################################################################################################## -terarium.baseUrl=http://localhost:8080 ######################################################################################################################## # Server configuration ######################################################################################################################## -aws-url= ######################################################################################################################## -# aws credentials configuration +# AWS credentials configuration ######################################################################################################################## -terarium.file-storage-s3-bucket-name=askem-beta-data-service ######################################################################################################################## -# Microservice configurations +# Microservice configuration ######################################################################################################################## -github.url=https://api.github.com -jsdelivr.url=https://cdn.jsdelivr.net -mira-api.url=http://34.230.33.149:8771 -model-service.url=https://model-service.beta.terarium.ai -skema-py.url=https://skema-py.beta.terarium.ai -skema-rs.url=https://skema-rs.beta.terarium.ai -skema-unified.url=https://api.askem.lum.ai -terarium.dataservice.url=https://data-service.beta.terarium.ai -xdd-dev-service.url=https://xdddev.chtc.io -xdd-prod-service.url=https://xdd.wisc.edu -simulation-service.url=https://sciml-service.beta.terarium.ai -ciemss-service.url=https://pyciemss.beta.terarium.ai ######################################################################################################################## # Beaker configuration ######################################################################################################################## -tgpt.base.url=https://app.beta.terarium.ai/beaker/ -tgpt.app.url=https://app.beta.terarium.ai/beaker/ -tgpt.ws.url=wss://app.beta.terarium.ai/beaker_ws/ ######################################################################################################################## -# ReBAC Configuration +# ReBAC configuration +######################################################################################################################## + +######################################################################################################################## +# RabbitMQ configuration +######################################################################################################################## + +######################################################################################################################## +# Neo4j configuration +######################################################################################################################## + +######################################################################################################################## +# Redis configuration +######################################################################################################################## + +######################################################################################################################## +# TaskRunner configuration +######################################################################################################################## + +######################################################################################################################## +# Logging +######################################################################################################################## + +######################################################################################################################## +# Cache Logging +######################################################################################################################## + +######################################################################################################################## +# Hibernate Logging ######################################################################################################################## -spicedb.target=spicedb.beta.terarium.ai:443 ######################################################################################################################## -# RabbitMQ exchange +# Hypersistence configuration ######################################################################################################################## -spring.rabbitmq.addresses=amqps://b-9fa42fad-d3db-45da-97ca-4f474b9dd847.mq.us-east-1.amazonaws.com:5671 ######################################################################################################################## -# neo4j configuration +# Feign client configuration ######################################################################################################################## -spring.neo4j.uri=bolt://graphdb.beta.terarium.ai:7687 -spring.neo4j.authentication.username=${neo4j-username} -spring.neo4j.authentication.password=${neo4j-password} diff --git a/packages/server/src/main/resources/application-staging.properties b/packages/server/src/main/resources/application-staging.properties new file mode 100644 index 0000000000..c489db0c3c --- /dev/null +++ b/packages/server/src/main/resources/application-staging.properties @@ -0,0 +1,104 @@ +######################################################################################################################## +# Database configuration +######################################################################################################################## +spring.datasource.url=jdbc:postgresql://postgres.staging.terarium.ai:5432/terarium + +######################################################################################################################## +# Elasticsearch configuration +######################################################################################################################## +terarium.elasticsearch.url=https://elasticsearch.staging.terarium.ai:443 + +######################################################################################################################## +# Flyway configuration +######################################################################################################################## + +######################################################################################################################## +# Request Logging +######################################################################################################################## + +######################################################################################################################## +# Caching +######################################################################################################################## + +######################################################################################################################## +# Keycloak configuration +######################################################################################################################## +terarium.keycloak.url=https://keycloak.staging.terarium.ai + +######################################################################################################################## +# Application configuration +######################################################################################################################## + +######################################################################################################################## +# Server configuration +######################################################################################################################## +terarium.swagger.server-url=https://server.staging.terarium.ai + +######################################################################################################################## +# AWS credentials configuration +######################################################################################################################## +aws-url= +terarium.file-storage-s3-bucket-name=askem-staging-data-service + +######################################################################################################################## +# Microservice configuration +######################################################################################################################## +mit-proxy.url=https://mit-tr.staging.terarium.ai +skema-py.url=https://skema-py.staging.terarium.ai +skema-rs.url=https://skema-rs.staging.terarium.ai +skema-unified.url=https://skema-unified.staging.terarium.ai +cosmos-service.url=https://cosmos.staging.terarium.ai +simulation-service.url=https://sciml-service.staging.terarium.ai +ciemss-service.url=https://pyciemss.staging.terarium.ai +climate-data-service.url=https://climate-data.staging.terarium.ai + +######################################################################################################################## +# Beaker configuration +######################################################################################################################## +tgpt.base.url=https://app.staging.terarium.ai/beaker/ +tgpt.app.url=https://app.staging.terarium.ai/beaker/ +tgpt.ws.url=wss://app.staging.terarium.ai/beaker_ws/ + +######################################################################################################################## +# ReBAC configuration +######################################################################################################################## +spicedb.target=spicedb.staging.terarium.ai:443 + +######################################################################################################################## +# RabbitMQ configuration +######################################################################################################################## +spring.rabbitmq.addresses=amqp://rabbitmq.staging.terarium.ai:5672 + +######################################################################################################################## +# Neo4j configuration +######################################################################################################################## +spring.neo4j.uri=bolt://graphdb.staging.terarium.ai:7687 + +######################################################################################################################## +# Redis configuration +######################################################################################################################## +spring.data.redis.url=https://redis.staging.terarium.ai + +######################################################################################################################## +# TaskRunner configuration +######################################################################################################################## + +######################################################################################################################## +# Logging +######################################################################################################################## + +######################################################################################################################## +# Cache Logging +######################################################################################################################## + +######################################################################################################################## +# Hibernate Logging +######################################################################################################################## + +######################################################################################################################## +# Hypersistence configuration +######################################################################################################################## + +######################################################################################################################## +# Feign client configuration +######################################################################################################################## diff --git a/packages/server/src/main/resources/application.properties b/packages/server/src/main/resources/application.properties index c88bfead97..06942dea70 100644 --- a/packages/server/src/main/resources/application.properties +++ b/packages/server/src/main/resources/application.properties @@ -1,7 +1,7 @@ ######################################################################################################################## # Database configuration ######################################################################################################################## -spring.datasource.url=jdbc:postgresql://postgres.staging.terarium.ai:5432/terarium +spring.datasource.url=jdbc:postgresql://10.64.22.49:5432/terarium spring.datasource.password=${terarium.db.password} spring.datasource.username=${terarium.db.username} spring.datasource.initialize=false @@ -12,7 +12,10 @@ spring.flyway.enabled=false ######################################################################################################################## # Elasticsearch configuration ######################################################################################################################## -terarium.elasticsearch.url=https://elasticsearch.staging.terarium.ai:443 +terarium.elasticsearch.url=https://elasticsearch.dev.terarium.ai +terarium.elasticsearch.auth-enabled=true +terarium.elasticsearch.username=${es-username} +terarium.elasticsearch.password=${es-password} terarium.elasticsearch.index.prefix=tds terarium.elasticsearch.index.suffix=tera_2.0 terarium.elasticsearch.index.artifact-root=artifact @@ -29,11 +32,6 @@ terarium.elasticsearch.index.decapodes-configuration-root=decapodesconfiguration terarium.elasticsearch.index.decapodes-context-root=decapodescontext management.health.elasticsearch.enabled=false -######################################################################################################################## -# neo4j configuration -######################################################################################################################## -management.health.neo4j.enabled=false - ######################################################################################################################## # Flyway configuration ######################################################################################################################## @@ -55,10 +53,10 @@ terarium.clientConfig.clientLogShippingEnabled=false terarium.clientConfig.clientLogShippingIntervalMillis=3000 ######################################################################################################################## -# Keycloak Configuration +# Keycloak configuration ######################################################################################################################## -terarium.keycloak.url=https://keycloak.staging.terarium.ai -terarium.keycloak.realm=Terarium +terarium.keycloak.url=https://keycloak.dev.terarium.ai +terarium.keycloak.realm=terarium spring.security.oauth2.client.provider.keycloak.issuer-uri=${terarium.keycloak.url:localhost}/realms/${terarium.keycloak.realm:Terarium} spring.security.oauth2.client.registration.keycloak.client-id=${terarium.keycloak.client-id:app} spring.security.oauth2.resourceserver.jwt.issuer-uri=${terarium.keycloak.url:localhost}/realms/${terarium.keycloak.realm:Terarium} @@ -66,7 +64,7 @@ spring.security.oauth2.resourceserver.jwt.issuer-uri=${terarium.keycloak.url:loc terarium.keycloak.api-service-name=api-service ######################################################################################################################## -# application configuration +# Application configuration ######################################################################################################################## terarium.baseUrl=http://localhost:8080 terarium.unauthenticated-url-patterns[0]=/configuration/keycloak @@ -104,9 +102,10 @@ spring.servlet.multipart.max-file-size=4GB spring.servlet.multipart.max-request-size=4GB logging.level.org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver=ERROR + #swagger configuration terarium.enable-swagger=true -terarium.swagger.server-url=https://server.staging.terarium.ai +terarium.swagger.server-url=https://server.dev.terarium.ai springdoc.swagger-ui.oauth.clientId=${terarium.keycloak.client-id:app} springdoc.swagger-ui.disable-swagger-default-url=true springdoc.swagger-ui.operationsSorter=alpha @@ -115,18 +114,19 @@ springdoc.swagger-ui.path=/swagger-ui #File upload/download spring.mvc.async.request-timeout=-1 + #Pass error message in response server.error.include-message=always server.error.include-stacktrace=never - ######################################################################################################################## -# aws credentials configuration +# AWS credentials configuration ######################################################################################################################## +aws-url=http://s3.t1.uncharted.software terarium.download-encryption-key=${download-encryption-key} terarium.amazon.credentials.default.access-key=${aws-access-key-id} terarium.amazon.credentials.default.secret-key=${aws-secret-access-key} -terarium.file-storage-s3-bucket-name=askem-staging-data-service +terarium.file-storage-s3-bucket-name=askem-dev-data-service terarium.file-storage-s3-client-name=default terarium.dataset-path=datasets terarium.results-path=simulations @@ -139,40 +139,39 @@ terarium.amazon.s3.default.url=${aws-url} terarium.amazon.s3.default.credentials-id=default ######################################################################################################################## -# Microservice configurations +# Microservice configuration ######################################################################################################################## github.url=https://api.github.com jsdelivr.url=https://cdn.jsdelivr.net mira-api.url=http://34.230.33.149:8771 -mit-proxy.url=https://mit-tr.staging.terarium.ai -skema-py.url=https://skema-py.staging.terarium.ai -skema-rs.url=https://skema-rs.staging.terarium.ai -skema-unified.url=https://skema-unified.staging.terarium.ai -terarium.dataservice.url=https://data-service.staging.terarium.ai +mit-proxy.url=https://mit-tr.dev.terarium.ai +skema-py.url=https://skema-py.dev.terarium.ai +skema-rs.url=https://skema-rs.dev.terarium.ai +skema-unified.url=https://skema-unified.dev.terarium.ai xdd-dev-service.url=https://xdddev.chtc.io xdd-prod-service.url=https://xdd.wisc.edu -cosmos-service.url=https://cosmos.staging.terarium.ai -simulation-service.url=https://sciml-service.staging.terarium.ai -ciemss-service.url=https://pyciemss.staging.terarium.ai -climate-data-service.url=https://climate-data.staging.terarium.ai +cosmos-service.url=https://cosmos.dev.terarium.ai +simulation-service.url=https://sciml-service.dev.terarium.ai +ciemss-service.url=https://pyciemss.dev.terarium.ai +climate-data-service.url=https://climate-data.dev.terarium.ai ######################################################################################################################## # Beaker configuration ######################################################################################################################## -tgpt.base.url=https://app.staging.terarium.ai/beaker/ -tgpt.app.url=https://app.staging.terarium.ai/beaker/ -tgpt.ws.url=wss://app.staging.terarium.ai/beaker_ws/ +tgpt.base.url=https://app.dev.terarium.ai/beaker/ +tgpt.app.url=https://app.dev.terarium.ai/beaker/ +tgpt.ws.url=wss://app.dev.terarium.ai/beaker_ws/ ######################################################################################################################## -# ReBAC Configuration +# ReBAC configuration ######################################################################################################################## spicedb.launchmode=TLS -spicedb.target=spicedb.staging.terarium.ai:443 +spicedb.target=spicedb.dev.terarium.ai:443 ######################################################################################################################## -# RabbitMQ exchange +# RabbitMQ configuration ######################################################################################################################## -spring.rabbitmq.addresses=amqps://b-1cb71505-9454-4d81-8ca0-a0ee6faf5770.mq.us-east-1.amazonaws.com:5671 +spring.rabbitmq.addresses=amqp://rabbitmq.dev.terarium.ai:5672 spring.rabbitmq.username=${terarium.mq-username} spring.rabbitmq.password=${terarium.mq-password} terarium.client-user-event-queue=clientUserEventQueue @@ -183,14 +182,20 @@ terarium.simulation.sciml-broadcast-exchange=sciml-broadcast-exchange terarium.simulation.pyciemss-broadcast-exchange=pyciemss-broadcast-exchange ######################################################################################################################## -# neo4j configuration +# Neo4j configuration ######################################################################################################################## -spring.neo4j.uri=bolt://graphdb.staging.terarium.ai:7687 +management.health.neo4j.enabled=false +spring.neo4j.uri=bolt://graphdb.dev.terarium.ai:7687 spring.neo4j.authentication.username=${neo4j-username} spring.neo4j.authentication.password=${neo4j-password} ######################################################################################################################## -# TaskRunner +# Redis configuration +######################################################################################################################## +spring.data.redis.url=https://redis.dev.terarium.ai + +######################################################################################################################## +# TaskRunner configuration ######################################################################################################################## terarium.taskrunner.request-queue=terarium-request-queue terarium.taskrunner.response-exchange=terarium-response-exchange @@ -211,7 +216,7 @@ logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%level] %msg [%c:%L]%n #logging.level.org.springframework.cache=TRACE ######################################################################################################################## -# Hibernate Logging - WARNING - very verbose +# Hibernate Logging ######################################################################################################################## #spring.jpa.properties.hibernate.format_sql=true #logging.level.org.hibernate=info @@ -222,13 +227,13 @@ logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%level] %msg [%c:%L]%n #logging.level.org.hibernate.cache=debug ######################################################################################################################## -# Hypersistence Configuration +# Hypersistence configuration ######################################################################################################################## hypersistence.utils.jackson.object.mapper=software.uncharted.terarium.hmiserver.utils.HypersistenceObjectMapperSupplier hypersistence.utils.json.serializer=software.uncharted.terarium.hmiserver.utils.HypersistenceJsonSerializerSupplier ######################################################################################################################## -# Feign Client Configuration +# Feign client configuration ######################################################################################################################## spring.cloud.openfeign.client.config.default.readTimeout=300000 spring.cloud.openfeign.client.config.default.connect-timeout=10000 diff --git a/packages/server/src/main/resources/messages.properties b/packages/server/src/main/resources/messages.properties index f70f34fcc0..94dbc9dcf8 100644 --- a/packages/server/src/main/resources/messages.properties +++ b/packages/server/src/main/resources/messages.properties @@ -1,48 +1,62 @@ generic.unknown = Oops! Something went wrong. Please try again later. +generic.invalid-uuid = The ID you supplied is not a valid UUID. Please ensure that the ID is correct. +generic.io-error = An error occurred while trying to read or write data. Please try again later. artifact.not-found = We were unable to find the requested artifact. Please ensure that the artifact ID you supplied is correct or contact support. -artifact.unable-to-update = We were unable to update the artifact asset. Please try again later. artifact.unable-to-delete = We were unable to delete the artifact asset. Please try again later. - +artifact.unable-to-update = We were unable to update the artifact asset. Please try again later. asset.not-found = We were unable to find the requested asset. Please ensure that the ID you supplied is correct or contact support. asset.unable-to-create = We were unable to update the project asset. Please try again later. +code.filename-needed = You must supply a filename for the code asset. code.not-found = We were unable to find the requested code. Please ensure that the code ID you supplied is correct or contact support. -code.unable-to-update = We were unable to update the code asset. Please try again later. code.unable-to-delete = We were unable to delete the code asset. Please try again later. +code.unable-to-update = We were unable to update the code asset. Please try again later. dataset.not-found = We were unable to find the requested dataset. Please ensure that the dataset ID you supplied is correct or contact support. -dataset.unable-to-update = We were unable to update the dataset asset. Please try again later. dataset.unable-to-delete = We were unable to delete the dataset asset. Please try again later. +dataset.unable-to-update = We were unable to update the dataset asset. Please try again later. +dataset.files.not-found = We were unable to find any files associated with this dataset. This may be due to the service being unavailable, or the dataset being corrupted. Please re-upload the dataset or contact support. +document.extraction.not-done = The document extraction process has not yet completed, and we are unable to perform this task. Please try again later. document.not-found = We were unable to find the requested document. Please ensure that the dataset ID you supplied is correct or contact support. -document.unable-to-update = We were unable to update the dataset document. Please try again later. document.unable-to-delete = We were unable to delete the dataset document. Please try again later. +document.unable-to-update = We were unable to update the dataset document. Please try again later. -model.not-found = We were unable to find the requested model. Please ensure that the dataset ID you supplied is correct or contact support. -model.unable-to-update = We were unable to update the dataset model. Please try again later. -model.unable-to-delete = We were unable to delete the dataset model. Please try again later. +mit.service-unavailable = Terarium's text reading service (MIT-TR) is temporarily unavailable. Please try again later. +mit.file.unable-to-read = An error occurred while trying to parce the supplied files. Please try again later. +mit.internal-error = An unknown error occurred in Terarium's text reading service (MIT-TR), and it was not able to produce valid information based on your supplied model and documentation. Please check that your inputs are valid and try again. +model.not-found = We were unable to find the requested model. Please ensure that the model ID you supplied is correct or contact support. +model.unable-to-delete = We were unable to delete the dataset model. Please try again later. +model.unable-to-update = We were unable to update the dataset model. Please try again later. postgres.service-unavailable = Terarium's data storage is temporarily unavailable. Please try again later. projects.asset-already-added = An asset with the same ID already exists in another project project. Please verify that the asset is not already in another project or contact support. projects.asset-conflict = An asset with the same ID already exists in the project. Please verify that the asset is not already in the project or contact support. +projects.name-required = You must supply a name for the project. projects.not-found = We were unable to find the requested project. Please ensure that the project ID you supplied is correct or contact support. projects.unable-to-delete = We were unable to delete the project. Please try again later. -projects.unable-to-update = We were unable to update the project. Please try again later. projects.unable-to-get-permissions = Terarium was unable to determine read/write permissions. For safety reasons, we are unable to return results. Please try again later. +projects.unable-to-update = We were unable to update the project. Please try again later. projects.name-required = You must supply a name for the project. projects.import-parse-failure = We were unable to parse the import file. Please ensure that the file is in the correct format and try again. +rebac.permissions.unable-to-set = An unknown error occurred while trying to set project permissions. Please try again later. rebac.relationship-already-exists = You already have permissions set to access this resource. Please contact the system administrator to upgrade permissions. rebac.service-unavailable = The service that Terarium uses for security and authorization is temporarily unavailable. Please try again later. rebac.unauthorized-delete = You are not authorized to delete this resource. Please contact the project owner to upgrade permissions. rebac.unauthorized-read = You are not authorized to access this resource. Please contact the project owner to upgrade permissions. rebac.unauthorized-update = You are not authorized to update this resource. Please contact the project owner to upgrade permissions. -rebac.permissions.unable-to-set = An unknown error occurred while trying to set project permissions. Please try again later. + +skema.bad-code = Terarium's model service (SKEMA) did not return a valid model representation based on the provided code. This could be due to a number of code issues including syntax and semantic errors. Please review your code snippet and try again. +skema.bad-equations = Terarium's model service (SKEMA) did not return a valid model representation based on the provided equations. This could be due to invalid equations or the inability to parse them into the requested framework. +skema.error.align-model = An error occurred while trying to align the model with the supplied document. Please ensure that the model is valid and that the document has valid extractions. +skema.internal-error = An error occurred in Terarium's model service (SKEMA), and it was not able to produce a valid model representation based on the provided resource. Please check that it is valid and try again. +skema.service-unavailable = Terarium's model service (SKEMA) is temporarily unavailable. Please try again later. workflow.not-found = We were unable to find the requested workflow. Please ensure that the workflow ID you supplied is correct or contact support. -workflow.unable-to-update = We were unable to update the workflow asset. Please try again later. workflow.unable-to-delete = We were unable to delete the workflow asset. Please try again later. +workflow.unable-to-update = We were unable to update the workflow asset. Please try again later. diff --git a/packages/server/src/test/java/software/uncharted/terarium/hmiserver/configuration/TestReBACService.java b/packages/server/src/test/java/software/uncharted/terarium/hmiserver/configuration/TestReBACService.java index 3c72ad76a4..2c07d2eb0c 100644 --- a/packages/server/src/test/java/software/uncharted/terarium/hmiserver/configuration/TestReBACService.java +++ b/packages/server/src/test/java/software/uncharted/terarium/hmiserver/configuration/TestReBACService.java @@ -74,12 +74,14 @@ void init() { } } + @Override public PermissionGroup createGroup(final String name) { final String id = UUID.randomUUID().toString(); groups.put(name, null); return new PermissionGroup(id, name); } + @Override public PermissionUser getUser(final String id) { for (final User user : USERS) { if (user.getId() == id) { @@ -89,14 +91,17 @@ public PermissionUser getUser(final String id) { throw new RuntimeException("User not found for id: " + id); } + @Override public List getUsers() { return new ArrayList<>(users.values()); } + @Override public List getRoles() { return new ArrayList<>(roles.values()); } + @Override public List getGroups() { final List response = new ArrayList<>(); for (final Map.Entry group : groups.entrySet()) { @@ -106,6 +111,7 @@ public List getGroups() { return response; } + @Override public PermissionGroup getGroup(final String id) { if (groups.containsKey(id)) { return new PermissionGroup(id, groups.get(id)); @@ -121,6 +127,7 @@ public boolean canWrite(final SchemaObject who, final SchemaObject what) throws return true; } + @Override public boolean isMemberOf(final SchemaObject who, final SchemaObject what) throws Exception { return true; } @@ -129,22 +136,27 @@ public boolean canAdministrate(final SchemaObject who, final SchemaObject what) return true; } + @Override public boolean isCreator(final SchemaObject who, final SchemaObject what) throws Exception { return true; } + @Override public void createRelationship( final SchemaObject who, final SchemaObject what, final Schema.Relationship relationship) throws Exception, RelationshipAlreadyExistsException {} + @Override public void removeRelationship( final SchemaObject who, final SchemaObject what, final Schema.Relationship relationship) throws Exception, RelationshipAlreadyExistsException {} + @Override public List getRelationships(final SchemaObject what) throws Exception { return new ArrayList<>(); } + @Override public ResponseEntity deleteRoleFromUser(final String roleName, final String userId) { if (!users.containsKey(userId)) { @@ -165,6 +177,7 @@ public ResponseEntity deleteRoleFromUser(final String roleName, final Stri return ResponseEntity.notFound().build(); } + @Override public ResponseEntity addRoleToUser(final String roleName, final String userId) { if (!users.containsKey(userId)) { @@ -195,6 +208,7 @@ public ResponseEntity addRoleToUser(final String roleName, final String us return ResponseEntity.ok().build(); } + @Override public List lookupResources( final SchemaObject who, final Schema.Permission permission, final Schema.Type type) throws Exception { diff --git a/packages/server/src/test/java/software/uncharted/terarium/hmiserver/controller/knowledge/KnowledgeControllerTests.java b/packages/server/src/test/java/software/uncharted/terarium/hmiserver/controller/knowledge/KnowledgeControllerTests.java index 3ec3245648..af0054fa3a 100644 --- a/packages/server/src/test/java/software/uncharted/terarium/hmiserver/controller/knowledge/KnowledgeControllerTests.java +++ b/packages/server/src/test/java/software/uncharted/terarium/hmiserver/controller/knowledge/KnowledgeControllerTests.java @@ -328,7 +328,7 @@ public void linkAmrTests() throws Exception { model = objectMapper.readValue(res.getResponse().getContentAsString(), Model.class); - Assertions.assertTrue(model != null); + Assertions.assertNotNull(model); } // @Test @@ -401,7 +401,7 @@ public void profileModel() throws Exception { model = modelService.getAsset(model.getId(), ASSUME_WRITE_PERMISSION).orElseThrow(); - Assertions.assertTrue(model.getMetadata().getCard() != null); + Assertions.assertNotNull(model.getMetadata().getCard()); } // @Test @@ -472,7 +472,7 @@ public void profileDataset() throws Exception { .getAsset(dataset.getId(), ASSUME_WRITE_PERMISSION) .orElseThrow(); - Assertions.assertTrue(dataset.getMetadata().get("dataCard") != null); + Assertions.assertNotNull(dataset.getMetadata().get("dataCard")); } // @Test @@ -505,7 +505,7 @@ public void codeToAmrTest() throws Exception { .andReturn(); final Model model = objectMapper.readValue(res.getResponse().getContentAsString(), Model.class); - Assertions.assertTrue(model != null); + Assertions.assertNotNull(model); } // @Test @@ -539,7 +539,7 @@ public void codeToAmrTestLLM() throws Exception { .andReturn(); final Model model = objectMapper.readValue(res.getResponse().getContentAsString(), Model.class); - Assertions.assertTrue(model != null); + Assertions.assertNotNull(model); } // @Test @@ -573,6 +573,6 @@ public void codeToAmrTestDynamicsOnly() throws Exception { .andReturn(); final Model model = objectMapper.readValue(res.getResponse().getContentAsString(), Model.class); - Assertions.assertTrue(model != null); + Assertions.assertNotNull(model); } } diff --git a/packages/server/src/test/resources/application-test.properties b/packages/server/src/test/resources/application-test.properties index 1c6e941412..d36096e066 100644 --- a/packages/server/src/test/resources/application-test.properties +++ b/packages/server/src/test/resources/application-test.properties @@ -2,21 +2,14 @@ # TODO: eventually we should have different profiles for local and CI testing, or the same datasource for both. ######################################################################################################################## -# other keys +# Other keys ######################################################################################################################## adobe_key=nothing google-analytics-id=nothing tgpt.token=nothing - adobe.api_key=${adobe_key} - -######################################################################################################################## -# xdd configuration -######################################################################################################################## - xdd_api_key=nothing xdd_es_key=nothing - xdd.api_key=${xdd_api_key} xdd.api_es_key=${xdd_es_key} @@ -26,6 +19,9 @@ xdd.api_es_key=${xdd_es_key} spring.datasource.url=jdbc:postgresql://localhost:5430/terarium spring.datasource.password=postgres spring.datasource.username=postgres +spring.datasource.initialize=true +spring.jpa.hibernate.ddl-auto=update +spring.flyway.enabled=true ######################################################################################################################## # Elasticsearch configuration @@ -35,9 +31,51 @@ terarium.elasticsearch.auth-enabled=false terarium.elasticsearch.index.prefix=tds_test ######################################################################################################################## -# Microservice configurations +# Flyway configuration +######################################################################################################################## + +######################################################################################################################## +# Request Logging +######################################################################################################################## + +######################################################################################################################## +# Caching +######################################################################################################################## + +######################################################################################################################## +# Keycloak configuration +######################################################################################################################## +terarium.keycloak.url=http://localhost:8081 +terarium.keycloak.realm=Terarium +terarium.keycloak.client-id=app +terarium.keycloak.admin-realm=master +terarium.keycloak.admin-client-id=admin-cli +terarium.keycloak.admin-username=admin +terarium.keycloak.admin-password=admin123 +spring.security.oauth2.client.provider.keycloak.issuer-uri= "http://keycloak:8081/realms/Terarium" +spring.security.oauth2.client.registration.keycloak.client-id= "app" +spring.security.oauth2.resourceserver.jwt.issuer-uri= "http://keycloak:8081/realms/Terarium" + +######################################################################################################################## +# Application configuration +######################################################################################################################## + +######################################################################################################################## +# Server configuration +######################################################################################################################## +terarium.swagger.server-url=http://localhost:3000 + +######################################################################################################################## +# AWS credentials configuration +######################################################################################################################## +aws-access-key-id=admin +aws-secret-access-key=admin123 +aws-url=http://localhost:9000 +terarium.file-storage-s3-bucket-name=askem-test-storage + +######################################################################################################################## +# Microservice configuration ######################################################################################################################## -terarium.dataservice.url=http://localhost:3020 ######################################################################################################################## # Beaker configuration @@ -47,56 +85,51 @@ tgpt.app.url=http://localhost:8080/beaker/ tgpt.ws.url=ws://localhost:8080/beaker_ws/ ######################################################################################################################## -# ReBAC Configuration +# ReBAC configuration ######################################################################################################################## -#spicedb.launchmode=PLAINTEXT -#spicedb.shared-key=dev -#spicedb.target=localhost:50051 spicedb.launchmode=TEST spicedb.target=TEST spicedb.shared-key=TEST ######################################################################################################################## -# aws credentials configuration +# RabbitMQ configuration ######################################################################################################################## -aws-access-key-id=admin -aws-secret-access-key=admin123 -aws-url=http://localhost:9000 +spring.rabbitmq.addresses=amqp://localhost:5672 +terarium.mq-username=terarium +terarium.mq-password=terarium123 ######################################################################################################################## -# neo4j configuration +# Neo4j configuration ######################################################################################################################## spring.neo4j.uri=bolt://localhost:7687 -spring.neo4j.authentication.username=neo4j -spring.neo4j.authentication.password=password +neo4j-username=neo4j +neo4j-password=password ######################################################################################################################## -# redis configuration +# Redis configuration ######################################################################################################################## spring.data.redis.url=redis://localhost:6379 ######################################################################################################################## -# keycloak configuration +# TaskRunner configuration ######################################################################################################################## -terarium.keycloak.url=http://localhost:8081 -terarium.keycloak.realm=Terarium -terarium.keycloak.client-id=app -terarium.keycloak.admin-realm=master -terarium.keycloak.admin-client-id=admin-cli -terarium.keycloak.admin-username=admin -terarium.keycloak.admin-password=admin123 -spring.security.oauth2.client.provider.keycloak.issuer-uri= "http://keycloak:8081/realms/Terarium" -spring.security.oauth2.client.registration.keycloak.client-id= "app" -spring.security.oauth2.resourceserver.jwt.issuer-uri= "http://keycloak:8081/realms/Terarium" +######################################################################################################################## +# Logging +######################################################################################################################## ######################################################################################################################## -# mq configuration +# Cache Logging +######################################################################################################################## + +######################################################################################################################## +# Hibernate Logging +######################################################################################################################## + +######################################################################################################################## +# Hypersistence configuration +######################################################################################################################## + +######################################################################################################################## +# Feign client configuration ######################################################################################################################## -terarium.mq-username=terarium -terarium.mq-password=terarium123 -terarium.mq.host="rabbitmq" -terarium.mq.port=5672 -spring.rabbitmq.addresses=amqp://localhost:5672 -spring.rabbitmq.username=${terarium.mq-username} -spring.rabbitmq.password=${terarium.mq-password}