Compare commits

...
208 Commits
Author SHA1 Message Date
Arthur Simas 4e2e6787a4 Merge branch 'feat/change-password' into main 2022-05-30 18:27:02 -03:00
Arthur Simas 50da33b766 FEAT: added verifyPasswordResetCode endpoint 2022-05-30 17:17:50 -03:00
Rodrigo Zamboni bb72cfce45 Merge pull request #100 from dadosfera/tests
Tests
2022-05-30 10:57:23 -03:00
rodrigo.zamboni 03d17758ae FIX: commented broken test 2022-05-30 10:11:04 -03:00
rodrigo.zamboni b7e76a6d3f FIX: fix busboy npm critical error 2022-05-30 09:58:07 -03:00
Arthur Simas c920eb27b9 FEAT: reset password 2022-05-27 18:57:05 -03:00
Arthur Simas c25d2427c2 FEAT: change password 2022-05-27 18:55:43 -03:00
Arthur Simas 0f13d0c590 FIX(refresh token): removed username param 2022-05-27 18:55:35 -03:00
Arthur Simas 7781298e6e Merge branch 'hotfix/refresh-token-contract' into fix/create-partial-input 2022-05-27 15:25:00 -03:00
Arthur Simas 2c00d3249a FIX(refresh token): removed username param 2022-05-27 15:12:22 -03:00
Arthur Simas cd7c7d538f CI: deploy workflow updated 2022-05-26 15:38:36 -03:00
rodrigo.zamboni e496d42776 ódio 2022-05-26 10:13:42 -03:00
Gabriel Rosa a07247d538 update protospack version 2022-05-25 15:49:45 -03:00
Arthur Simas 153ba1a98b CI: printing env 2022-05-25 12:24:50 -03:00
Gabriel Rosa 46519323f8 Ci: imporved github flow 2022-05-25 11:56:26 -03:00
Arthur Simas a51d52d68e CI: fixed versioning 2022-05-25 11:53:44 -03:00
Gabriel Rosa 555ff2eda9 CI - github flow melhorado 2022-05-25 11:52:54 -03:00
Arthur Simas 5d1a54a720 CI: . 2022-05-25 11:45:37 -03:00
Arthur Simas 8399a0e4c1 CI: . 2022-05-25 11:40:38 -03:00
Arthur Simas cf54cb0bc2 CI: not considering semver during manual deploy 2022-05-25 11:37:14 -03:00
rodrigo.zamboni 4eba099390 Merge branch 'main' of https://github.com/dadosfera/maestro into tests 2022-05-25 11:14:45 -03:00
rodrigo.zamboni 08fa269ce0 initial tests 2022-05-25 11:14:40 -03:00
Gabriel Rosa e52af6844b FIX: create partial input 2022-05-25 11:09:24 -03:00
Arthur Simas 2344e4dba3 CI: using github-flow deployment workflow 2022-05-24 18:57:41 -03:00
rodrigo.zamboni d686753f25 DOCS: Added proper readme 2022-05-23 17:19:36 -03:00
Rodrigo Zamboni c1498f8f1b Merge pull request #98 from dadosfera/beta
Beta -> main
2022-05-20 17:27:29 -03:00
Gabriel Rosa 0b3cb581c4 merge alpha -> beta 2022-05-20 15:19:43 -03:00
Gabriel Rosa 97a6e05812 FIX: returning input when creating jdbc 2022-05-20 15:19:00 -03:00
Gabriel Rosa 356d438404 merge alpha 2022-05-20 14:07:02 -03:00
Gabriel Rosa cf870cff14 FIX: formating payload 2022-05-20 14:06:13 -03:00
Gabriel Rosa 26c6a289eb merge from beta 2022-05-20 11:51:48 -03:00
Gabriel Rosa 8d27e42fcd FIX: protospack version 2022-05-20 11:51:08 -03:00
Gabriel Rosa c44e557b11 merge beta 2022-05-20 10:08:20 -03:00
Gabriel Rosa 25d06ab4c5 FIX: send input to createS3 2022-05-20 10:07:38 -03:00
Gabriel Amorim 31bb795d23 Merge pull request #97 from dadosfera/alpha
Alpha -> Beta
2022-05-20 09:12:34 -03:00
Gabriel Rosa a2e25eb737 FIX: added ssl back 2022-05-20 08:51:25 -03:00
Gabriel Rosa 6be53bebaf FIX: adjusting pipeline payload fixed 2022-05-20 08:50:08 -03:00
Rodrigo Zamboni 741f009723 Merge pull request #96 from dadosfera/alpha
Alpha
2022-05-19 15:20:06 -03:00
Rodrigo Zamboni 45477b5750 Merge branch 'beta' into alpha 2022-05-19 15:09:15 -03:00
rodrigo.zamboni 36de53dfd3 FIX: lib version 2022-05-19 14:48:22 -03:00
rodrigo.zamboni cd8fe2fbf6 CI: Deploy 2022-05-19 14:46:17 -03:00
rodrigo.zamboni c4a2bee69c CI: DEploy 2022-05-19 14:18:08 -03:00
rodrigo.zamboni e48d11153d FIX: Added S3 or JDBC input selection for pipelines 2022-05-19 14:13:06 -03:00
Gabriel Amorim c7e4de7d65 Merge pull request #95 from dadosfera/feat/mfa
FEAT: MFA finished + better error handling
2022-05-19 13:59:46 -03:00
Arthur Simas b2e7870cc5 CHORE: protospack version bump 2022-05-19 12:56:32 -03:00
Arthur Simas 1e239026a3 FEAT: MFA finished + better error handling 2022-05-19 12:02:08 -03:00
Rodrigo Zamboni bc108d43e3 Merge pull request #94 from dadosfera/beta
Beta
2022-05-18 16:54:04 -03:00
Arthur Simas 1c5b929c1b REFACTOR: nimbus URL 2022-05-18 13:57:19 -03:00
rodrigo.zamboni 3e21c308f6 UPDATE: Added S3 Input Creation 2022-05-17 15:58:18 -03:00
Gabriel Rosa f4a5f91cbb FIX: remove backmerge 2022-05-16 17:03:12 -03:00
Gabriel Rosa c8aeb7f3db FIX: remove backmerge 2022-05-16 17:02:46 -03:00
Victor Radael b9453b11cf REFACTOR: Init Catalog Class 2022-05-16 14:02:18 -03:00
Victor Radael a69752332e FIX: Nimbus URL Strategy 2022-05-16 13:42:06 -03:00
Victor Radael 09c7cc79ee FIX: Nimbus URL Strategy 2022-05-16 12:04:13 -03:00
Arthur Simas 65f6f03e55 CHORE: pinning protospack version to 1.7.4 2022-05-13 11:15:05 -03:00
Arthur Simas a54300f600 CHORE: pinning protospack version to 1.7.2 2022-05-13 11:00:25 -03:00
Arthur Simas 5ef85f79d3 Merge branch 'alpha' into beta 2022-05-13 10:49:27 -03:00
rodrigo.zamboni a8a429977f UPDATE: Implementing MFA routes on maestro 2022-05-11 18:02:01 -03:00
Gabriel Amorim 692a9de0af FEAT: add refresh token - Merge pull request #90 from dadosfera/feat/refreshToken
FEATURE: add refresh token
2022-05-11 10:37:36 -03:00
rodrigo.zamboni 7dc669ca44 FIX: fix auth trim 2022-05-10 15:53:47 -03:00
rodrigo.zamboni e897da1ef0 FIX: Fix login middleware 2022-05-10 15:32:34 -03:00
Arthur Simas b366e786ba STYLE: styling conforming to ESLint 2022-05-10 10:23:55 -03:00
Arthur Simas 24d56c7a58 FEAT: add refresh token 2022-05-09 11:47:25 -03:00
rodrigo.zamboni d7f205901b UPDATE: Changing transformation factory microservice client url to inputs factory 2022-05-05 16:27:20 -03:00
rodrigo.zamboni 7212c5249c FIX: testing timeout on testconnection input client 2022-05-04 16:44:00 -03:00
rodrigo.zamboni 827c7b1bf1 FIX: Summary-rating returning default 0 values 2022-05-04 12:00:01 -03:00
rodrigo.zamboni 8d89b747b4 FIX: Fix delete routes method 2022-05-04 00:24:44 -03:00
rodrigo.zamboni 4f18328603 FIX: update protospack lib version 2022-05-03 17:59:51 -03:00
rodrigo.zamboni a68d312447 FIX: updated protospack lib 2022-05-03 17:07:57 -03:00
rodrigo.zamboni 7f677f0376 FIX: Fix mistaken routes method 2022-05-03 16:54:03 -03:00
rodrigo.zamboni bb2c0ab23e Merge branch 'main' of https://github.com/dadosfera/maestro into main 2022-05-03 15:13:10 -03:00
rodrigo.zamboni feec48114c FIX: fixed missing nimbus catalog routes 2022-05-03 15:12:18 -03:00
Rodrigo Zamboni 7bee8d83a9 Merge pull request #89 from dadosfera/beta
Beta
2022-05-03 09:14:43 -03:00
Rodrigo Zamboni 84b2dbd178 Merge pull request #88 from dadosfera/alpha
CI: Deploy on dev env
2022-05-02 17:53:46 -03:00
rodrigo.zamboni 36706ff3dd CI: Deploy on dev env 2022-05-02 17:33:03 -03:00
Victor Radael 0164e6978a FIX: Metabase URL 2022-04-29 20:53:17 -03:00
rodrigo.zamboni 7d371926f5 FIX: fix nimbus prd url 2022-04-29 17:20:23 -03:00
rodrigo.zamboni 75e9e97f04 FIX: fix nimbus prd url 2022-04-29 17:18:21 -03:00
rodrigo.zamboni b5f58b99fd FIX: Changing nimbus prd url 2022-04-29 16:33:42 -03:00
rodrigo.zamboni 503293439f FIX: updating protospack lib version 2022-04-29 16:14:14 -03:00
rodrigo.zamboni eed57ff039 FIX: fix pipeline status sort 2022-04-29 12:42:49 -03:00
rodrigo.zamboni ef2a24a0c3 FIX: Fix runPipeline fail case return 2022-04-28 17:39:05 -03:00
Rodrigo Zamboni 8a31e11445 Merge pull request #87 from dadosfera/beta
Beta
2022-04-28 17:23:54 -03:00
Rodrigo Zamboni 2013e97e20 Merge pull request #86 from dadosfera/alpha
Alpha
2022-04-28 17:12:53 -03:00
rodrigo.zamboni dd271205ba Merge branch 'alpha' of https://github.com/dadosfera/maestro into alpha 2022-04-28 17:00:44 -03:00
rodrigo.zamboni a1f9f14897 FIX: Fixing more catalog routes params 2022-04-28 17:00:08 -03:00
Gabriel Amorim b7efa2f58d Merge pull request #85 from dadosfera/beta
Beta -> Main
2022-04-28 16:04:10 -03:00
Gabriel Amorim 395e36581d Merge pull request #84 from dadosfera/alpha
Alpha -> Beta
2022-04-28 16:03:53 -03:00
rodrigo.zamboni 97a54f9267 Merge branch 'alpha' of https://github.com/dadosfera/maestro into alpha 2022-04-28 15:56:30 -03:00
rodrigo.zamboni 00b0e00bd0 FIX: fix iframe_url and pipeline status 2022-04-28 15:55:48 -03:00
Rodrigo Zamboni 9188536161 Merge pull request #83 from dadosfera/beta
Beta
2022-04-28 14:53:16 -03:00
Rodrigo Zamboni 1ae8151184 Merge pull request #82 from dadosfera/alpha
Alpha -> Beta
2022-04-28 14:40:14 -03:00
rodrigo.zamboni 3d77980dd2 CI: deploy 2022-04-28 14:24:28 -03:00
Rodrigo Zamboni 849b979e63 Merge pull request #81 from dadosfera/feat/CatalogFixes
Feat/catalog fixes
2022-04-28 14:19:31 -03:00
rodrigo.zamboni 28580782b1 FIX: catalog routes fix 2022-04-28 14:14:03 -03:00
Rodrigo Zamboni fc784e2d6d Merge pull request #79 from dadosfera/alpha
Alpha
2022-04-28 13:22:14 -03:00
rodrigo.zamboni c997e91912 FIX: fix table-metadata find one route 2022-04-28 12:59:35 -03:00
rodrigo.zamboni 22f493d48a FIX: fixing missing id on delete routes 2022-04-28 12:12:37 -03:00
rodrigo.zamboni 035213824b FIX: fixing missing id on delete routes 2022-04-28 12:00:19 -03:00
rodrigo.zamboni 1ffa9ade51 FIX: CI 2022-04-28 10:53:17 -03:00
Rodrigo Zamboni c91aa57344 Merge pull request #78 from dadosfera/beta
Beta
2022-04-27 17:36:54 -03:00
Rodrigo Zamboni 077a95cdbd Merge pull request #77 from dadosfera/alpha
Alpha
2022-04-27 17:16:09 -03:00
Rodrigo Zamboni f39108772b Merge pull request #76 from dadosfera/NewInput
FIX: fix pipeline activate route method
2022-04-27 16:57:56 -03:00
rodrigo.zamboni cdd8beee8f FIX: fix pipeline activate route method 2022-04-27 16:56:03 -03:00
rodrigo.zamboni 14331ed229 FIX: fix pipeline activate route method 2022-04-27 16:54:48 -03:00
Victor Radael 5f3db0cb43 Merge pull request #75 from dadosfera/beta
Beta -> Main
2022-04-27 11:42:18 -03:00
Rodrigo Zamboni 28f304c47c Merge pull request #74 from dadosfera/alpha
Alpha
2022-04-26 17:41:57 -03:00
Rodrigo Zamboni 0c1b62b2aa Merge pull request #73 from dadosfera/NewInput
FIX: Fix get-columns route method
2022-04-26 17:25:11 -03:00
rodrigo.zamboni 13f7e9d812 FIX: Fix get-columns route method 2022-04-26 17:19:18 -03:00
Gabriel Amorim 841dcfef06 Merge pull request #72 from dadosfera/alpha
Alpha
2022-04-26 16:30:31 -03:00
Gabriel Amorim f41ddc1483 Merge pull request #71 from dadosfera/NewInput
UPDATE: Implemented new Input format
2022-04-26 16:19:19 -03:00
rodrigo.zamboni 0a2c7c0a38 UPDATE: Implemented new Input format 2022-04-26 16:15:54 -03:00
Rodrigo Zamboni 87f4c17ca2 Merge pull request #70 from dadosfera/beta
Beta
2022-04-26 13:50:00 -03:00
Rodrigo Zamboni a89625c1e6 Merge pull request #69 from dadosfera/alpha
Alpha
2022-04-26 11:16:06 -03:00
rodrigo.zamboni 44211d5658 FIX: CI 2022-04-26 11:01:20 -03:00
rodrigo.zamboni d4e11b1935 FIX: CI 2022-04-26 10:48:57 -03:00
rodrigo.zamboni 5c5e940cf7 FIX: CI 2022-04-26 10:40:11 -03:00
Rodrigo Zamboni 2b162bd0a7 Merge pull request #68 from dadosfera/beta
Beta
2022-04-25 17:06:59 -03:00
Victor Radael 829f7611e2 Merge pull request #67 from dadosfera/alpha
Alpha
2022-04-25 16:49:04 -03:00
Rodrigo Zamboni b986cf3281 Merge pull request #66 from dadosfera/addHelmet
FIX: added helmet package to protect headers security
2022-04-25 16:35:59 -03:00
rodrigo.zamboni 75c7602e13 FIX: added helmet package to protect headers security 2022-04-25 16:25:42 -03:00
Victor Radael 710105a4a8 Merge pull request #65 from dadosfera/addHelmet
added helmet package to protect headers security
2022-04-25 16:16:07 -03:00
rodrigo.zamboni 30b048f776 added helmet package to protect headers security 2022-04-25 16:11:50 -03:00
Victor Radael 845b95b112 Merge pull request #64 from dadosfera/beta
Beta ->  main
2022-04-21 17:15:16 -03:00
Victor Radael 6d6b024884 Merge pull request #63 from dadosfera/alpha
Alpha -> Beta
2022-04-21 16:18:51 -03:00
Rodrigo Zamboni a4282a0dc5 Merge pull request #62 from dadosfera/feat/nimbusImplementation
Feat/nimbus implementation
2022-04-21 16:05:37 -03:00
rodrigo.zamboni 4672ecb6b3 FIX: Fixed maestro after protospack lib att 2022-04-21 16:02:11 -03:00
rodrigo.zamboni 6160107d75 FIX: Downgrade protospack lib 2022-04-20 16:22:26 -03:00
Rodrigo Zamboni 589a1f9d51 Merge pull request #60 from dadosfera/feat/nimbusImplementation
Feat/nimbus implementation
2022-04-20 16:01:32 -03:00
rodrigo.zamboni cb929d9b60 FIX: FIX 2022-04-20 15:56:50 -03:00
rodrigo.zamboni 678bebef7e FIX: fix proto packages names 2022-04-20 15:52:26 -03:00
Rodrigo Zamboni b6d7d54f9c Merge pull request #58 from dadosfera/feat/nimbusImplementation
adding get all tags function
2022-04-20 15:30:40 -03:00
rodrigo.zamboni 5df8b2834c FIX: adding get all tags function 2022-04-20 15:08:51 -03:00
rodrigo.zamboni 76d9571f02 FIX: adding get all tags function 2022-04-20 14:51:04 -03:00
rodrigo.zamboni 0c51014ec9 adding get all tags function 2022-04-20 14:40:01 -03:00
Rodrigo Zamboni 7f1d8e4b2a Merge pull request #57 from dadosfera/beta
Beta
2022-04-19 18:29:16 -03:00
Victor Radael 92b78ff19d Merge pull request #56 from dadosfera/alpha
Alpha
2022-04-19 17:06:28 -03:00
Rodrigo Zamboni 1b328b9915 Merge pull request #55 from dadosfera/NimbusImplementation
UPDATE: Added Nimbus Catalog routes
2022-04-19 16:24:34 -03:00
rodrigo.zamboni e653aeea3c UPDATE: Added Nimbus Catalog routes 2022-04-19 15:56:29 -03:00
Rodrigo Zamboni b49633cbc2 Merge pull request #54 from dadosfera/beta
Beta
2022-04-18 13:58:14 -03:00
Rodrigo Zamboni 4d956e55c6 Merge pull request #53 from dadosfera/alpha
Alpha
2022-04-18 12:18:28 -03:00
Rodrigo Zamboni 735703bf3b Merge pull request #52 from dadosfera/feat/activatePipeline
Feat/activate pipeline
2022-04-18 11:54:43 -03:00
rodrigo.zamboni 93cdc3f030 UPDATE: remove unescessary console log 2022-04-18 11:50:17 -03:00
rodrigo.zamboni 12b8b5926c UPDATE: Created Trigger Pipeline route 2022-04-18 11:44:19 -03:00
rodrigo.zamboni 1643096d47 Created Trigger Pipeline route 2022-04-18 11:43:36 -03:00
Rodrigo Zamboni 8a519ac217 Merge pull request #51 from dadosfera/beta
Beta
2022-04-14 15:33:36 -03:00
Victor Radael ffa69a0cf5 Merge pull request #50 from dadosfera/alpha
Alpha
2022-04-14 15:14:12 -03:00
Rodrigo Zamboni 7722e380e3 Merge pull request #49 from dadosfera/authFix
FIX: using Unauth nest function
2022-04-14 15:01:18 -03:00
rodrigo.zamboni ecdc7b4eb6 FIX: using Unauth nest function 2022-04-14 14:56:18 -03:00
rodrigo.zamboni 7d14080ac1 FIX: Invalid auth credentials return 2022-04-14 14:48:40 -03:00
Victor Radael 7e7deba2ab FIX: CI 2022-04-12 18:10:40 -03:00
Victor Radael e425e90eeb FIX: CI 2022-04-12 17:59:41 -03:00
Victor Radael 45f35b4e39 Merge branch 'alpha' into main 2022-04-12 17:44:29 -03:00
Victor Radael d450acd007 FIX: CI 2022-04-12 17:43:46 -03:00
Victor Radael e9c1dfc320 Merge pull request #48 from dadosfera/beta
Beta
2022-04-12 17:20:18 -03:00
Rodrigo Zamboni 67484cbef8 Merge pull request #47 from dadosfera/alpha
Alpha
2022-04-12 17:07:57 -03:00
rodrigo.zamboni 740be1d98b FIX: CI 2022-04-12 16:20:03 -03:00
rodrigo.zamboni b9989d86c1 Merge branch 'alpha' of https://github.com/dadosfera/maestro into alpha 2022-04-12 16:15:25 -03:00
rodrigo.zamboni 9b3a127f6a fixed authorization on case of missing Authorization header 2022-04-12 16:15:04 -03:00
Victor Radael 55028c4b83 Merge pull request #46 from dadosfera/alpha
Alpha
2022-04-08 13:02:06 -03:00
Victor Radael 7d5dee4b0c FIX: Deploy 2022-04-08 12:48:40 -03:00
Victor Radael 708bf2f585 FIX: Deploy 2022-04-07 18:41:39 -03:00
Rodrigo Zamboni 1d53226540 Merge pull request #45 from dadosfera/alpha
FIX: CI
2022-04-07 18:12:58 -03:00
Victor Radael 5f6ae5d512 FIX: CI 2022-04-07 17:54:14 -03:00
Rodrigo Zamboni c51092260a Merge pull request #44 from dadosfera/alpha
Alpha
2022-04-07 16:54:25 -03:00
Victor Radael 3add8b026e Merge branch 'alpha' of https://github.com/dadosfera/maestro into alpha 2022-04-07 16:44:10 -03:00
Victor Radael 42726b805b FIX: Ci 2022-04-07 16:43:59 -03:00
Victor Radael 8d8c5c000e Merge pull request #43 from dadosfera/alpha
Deploy STG
2022-04-07 16:17:27 -03:00
rodrigo.zamboni b7f608f246 FIX: TestConnection Fix 2022-04-07 11:22:57 -03:00
rodrigo.zamboni e513689f4a REFACTOR: Att Functions to work with info given by auth 2022-03-30 11:32:59 -03:00
rodrigo.zamboni 761a00c6a6 removing default true value from auth 2022-03-29 18:16:18 -03:00
rodrigo.zamboni ef9cff601f Merge branch 'alpha' of https://github.com/dadosfera/maestro into alpha 2022-03-29 17:44:10 -03:00
rodrigo.zamboni a3ba9c743f Prepared Outputs and Transformations to use info params given by auth 2022-03-29 17:43:44 -03:00
Victor Radael 9dd3ec4579 FIX: Change Header Name 2022-03-29 15:44:53 -03:00
rodrigo.zamboni 8b19da9217 fixed merge conflicts 2022-03-29 15:22:42 -03:00
rodrigo.zamboni 238de920dc Prepared Inputs for info params added by auth 2022-03-29 15:18:35 -03:00
Victor Radael fe1a426e2b FIX: Add Cors Config 2022-03-29 15:16:37 -03:00
Victor Radael 1f85d3f502 FIX: Add Cors Config 2022-03-29 15:10:29 -03:00
rodrigo.zamboni c68207728b merge fix 2022-03-29 12:06:26 -03:00
rodrigo.zamboni c431867814 preparing info param 2022-03-29 12:04:10 -03:00
Victor Radael ca7f9855b1 Add body Info 2022-03-29 11:54:14 -03:00
Victor Radael 7a95ec537f REFACTOR: Add Auth Validators 2022-03-28 13:06:03 -03:00
Victor Radael 25d99089db CI: Fix 2022-03-24 14:44:26 -03:00
Victor Radael e336f31fda CI: Fix 2022-03-24 14:33:14 -03:00
Victor Radael 2bdb06494a CI: Fix 2022-03-24 13:54:53 -03:00
rodrigo.zamboni f94416200a CI: Deploy changes 2022-03-24 13:52:43 -03:00
rodrigo.zamboni 3bbd48894b CI: Fix deploy 2022-03-24 12:08:08 -03:00
Rodrigo Zamboni 1f1660cdf2 Merge pull request #42 from dadosfera/ft-int-duc
REFACTOR: Att Functions + Alpha Clients connection
2022-03-24 11:49:34 -03:00
Rodrigo Zamboni 3a7f392e8b Merge branch 'alpha' into ft-int-duc 2022-03-24 11:48:55 -03:00
rodrigo.zamboni 04584df44d REFACTOR: Att Functions + Alpha Clients connection 2022-03-24 11:41:55 -03:00
Victor Radael 26ec0b3dfb CI: Deploy 2022-03-21 10:56:46 -03:00
Victor Radael 44d4b8e08c CI: Deploy 2022-03-21 10:39:41 -03:00
Victor Radael 63fa756c9b Merge pull request #41 from dadosfera/ft-int-duc
Ft int duc
2022-03-21 10:24:05 -03:00
Victor Radael 91236dde86 CI: Deploy 2022-03-21 10:03:54 -03:00
rodrigo.zamboni a39ea091ee prepared tests to deploy 2022-03-18 15:20:32 -03:00
Rodrigo Zamboni 8787aa05c2 Merge pull request #40 from dadosfera/ft-int-duc
Ft int duc
2022-03-18 10:17:27 -03:00
rodrigo.zamboni 1523c6b4d1 maestro connection with microservices - clients and modules 2022-03-18 10:16:27 -03:00
Victor Radael e15a680b9f FIX: Health Check 2022-03-14 10:39:51 -03:00
Victor Radael 363bc8b350 REFACTOR: Project Pattern and AuthClient (DUC) 2022-03-14 10:35:03 -03:00
Victor Radael 2f8d9b9550 Merge pull request #39 from dadosfera/att-ci
CI: Att CI
2022-02-10 14:49:40 -03:00
Victor Radael e729e1f0f4 CI: Att CI 2022-02-10 14:47:06 -03:00
Victor Radael a20ff87b27 Merge pull request #38 from dadosfera/ft-att-doc
docs: Att docs
2022-02-10 14:37:58 -03:00
Victor Radael abf5c71c08 docs: Att docs 2022-02-10 14:32:42 -03:00
Alexsander Pereira 6b991bce7d Merge pull request #37 from dadosfera/ci
CI: Adding @semantic-release/npm to modify package.json on deploy
2022-02-10 12:21:00 -03:00
alexsanderp e007c2c49c CI: Adding @semantic-release/npm to modify package.json on deploy 2022-02-10 12:14:46 -03:00
Alexsander Pereira 99b7d9a8d7 Merge pull request #36 from dadosfera/beta
Beta to Main
2022-02-10 11:46:50 -03:00
Alexsander Pereira 688fe81500 Merge pull request #35 from dadosfera/alpha
CI: Adding @saithodev/semantic-release-backmerge to merge main into a…
2022-02-10 11:29:13 -03:00
alexsanderp f785253ece CI: Adding @saithodev/semantic-release-backmerge to merge main into alpha and beta after new release published 2022-02-10 11:16:04 -03:00
185 changed files with 14575 additions and 5254 deletions
+7
View File
@@ -0,0 +1,7 @@
Resources:
AWSEBAutoScalingLaunchConfiguration:
Properties:
MetadataOptions:
HttpEndpoint: enabled
HttpPutResponseHopLimit: 2
HttpTokens: required
+19
View File
@@ -0,0 +1,19 @@
branch-defaults:
alpha:
environment: null
global:
application_name: maestro
branch: null
default_ec2_keyname: null
default_platform: Docker running on 64bit Amazon Linux 2
default_region: us-east-1
include_git_submodules: true
instance_profile: null
platform_name: null
platform_version: null
profile: null
repository: null
sc: git
workspace_type: Application
deploy:
artifact: deploy.zip
+140
View File
@@ -0,0 +1,140 @@
name: Deploy
on:
push:
branches:
- main
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
type: choice
options:
- dev
- stg
- prd
jobs:
extract_environment:
runs-on: ubuntu-latest
outputs:
environment: ${{ steps.extract_environment.outputs.environment }}
env:
EVENT: ${{ github.event_name }}
DEPLOY_ENV: ${{ github.event.inputs.environment }}
steps:
- name: Extract Environment
run: |
if [ ${EVENT} == "workflow_dispatch" ]; then
echo "##[set-output name=environment;]$(echo ${DEPLOY_ENV})"
elif [ ${GITHUB_REF} == "refs/heads/main" ]; then
echo "##[set-output name=environment;]$(echo "prd")"
fi
id: extract_environment
semantic_release:
runs-on: ubuntu-latest
outputs:
#new_release_published: ${{ steps.semantic.outputs.last_release_version != steps.semantic.outputs.new_release_version }}
new_release_published: ${{ steps.semantic.outputs.new_release_published }}
#new_release_version: ${{ steps.semantic.outputs.new_release_version }}
new_release_version: ${{ (steps.semantic.outputs.new_release_published == 'true' && steps.semantic.outputs.new_release_version) || (github.event_name == 'workflow_dispatch' && '0.0.0') }}
steps:
- name: Checkout
uses: actions/checkout@v2
- if: github.event_name != 'workflow_dispatch'
name: Semantic Release
uses: cycjimmy/semantic-release-action@v2
id: semantic
with:
semantic_version: 16
extra_plugins: |
conventional-changelog-eslint
branches: |
[
'main'
]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
deploy:
if: ${{ github.event_name == 'workflow_dispatch' || needs.semantic_release.outputs.new_release_published == 'true' }}
needs: [extract_environment, semantic_release]
runs-on:
[self-hosted, '${{ needs.extract_environment.outputs.environment }}']
steps:
- name: Printing stats
env:
EVENT: ${{ github.event_name }}
IMAGE_TAG: ${{ needs.semantic_release.outputs.new_release_version }}
ENV: ${{ needs.extract_environment.outputs.environment }}
run: echo ${GITHUB_REF#refs/heads/}
- name: Checkout
uses: actions/checkout@v2
- name: Update Pip
run: |
python3 -m pip install --upgrade pip
- name: Install Docker Compose
run: |
python3 -m pip install docker-compose --upgrade
- name: Install AWS CLI
run: |
python3 -m pip install awscli --upgrade
- name: Install AWS Elastic Beanstalk CLI
run: |
python3 -m pip install awsebcli --upgrade
- name: Configure AWS Region
uses: aws-actions/configure-aws-credentials@v1
id: aws
with:
aws-region: us-east-1
- name: Login to AWS ECR
id: login_ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, Tag, and Push Image to AWS ECR
env:
ENV: ${{ needs.extract_environment.outputs.environment }}
IMAGE_TAG: ${{ needs.semantic_release.outputs.new_release_version }}
ACCOUNT_ID: ${{ steps.aws.outputs.aws-account-id }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
docker-compose -f build.docker-compose.yml build --build-arg NPM_TOKEN=${NPM_TOKEN}
docker-compose -f build.docker-compose.yml push
- name: Create ZIP file to Deploy AWS Beanstalk
env:
ENV: ${{ needs.extract_environment.outputs.environment }}
IMAGE_TAG: ${{ needs.semantic_release.outputs.new_release_version }}
ACCOUNT_ID: ${{ steps.aws.outputs.aws-account-id }}
run: |
sed -i -e "s/\${ENV}/$ENV/g" docker-compose.yml
sed -i -e "s/\${IMAGE_TAG}/$IMAGE_TAG/g" docker-compose.yml
sed -i -e "s/\${ACCOUNT_ID}/$ACCOUNT_ID/g" docker-compose.yml
zip deploy.zip docker-compose.yml -r .ebextensions
- name: Deploy AWS Beanstalk
env:
ENV: ${{ needs.extract_environment.outputs.environment }}
AWS_REGION: us-east-1
APP_NAME: ${{ github.event.repository.name }}
run: |
eb use $APP_NAME-$ENV
echo -e "deploy:\n artifact: deploy.zip" >> .elasticbeanstalk/config.yml
eb deploy
- name: Remove Docker's Trash
continue-on-error: true
run: |
docker system prune
docker rmi -f $(docker images -aq)
-103
View File
@@ -1,103 +0,0 @@
name: Deploy
on:
push:
branches:
- alpha
- beta
- main
jobs:
deploy:
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Semantic Release
uses: cycjimmy/semantic-release-action@v2
id: semantic
with:
semantic_version: 16
extra_plugins: |
conventional-changelog-eslint
branches: |
[
'main',
{
name: 'alpha',
prerelease: true
},
{
name: 'beta',
prerelease: true
}
]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update Pip
run: |
python3 -m pip install --upgrade pip
- name: Install Docker Compose
run: |
python3 -m pip install docker-compose --upgrade
- name: Install AWS CLI
run: |
python3 -m pip install awscli --upgrade
- name: Install AWS Elastic Beanstalk CLI
run: |
python3 -m pip install awsebcli --upgrade
- name: Configure AWS Region
uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: us-east-1
- name: Extract Environment
shell: bash
run: |
if [ ${GITHUB_REF} == "refs/heads/main" ]; then
echo "##[set-output name=result;]$(echo "production")"
else
echo "##[set-output name=result;]$(echo ${GITHUB_REF#refs/heads/})"
fi
id: extract_environment
- name: Login to AWS ECR
id: login_ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, Tag, and Push Image to AWS ECR
if: steps.semantic.outputs.new_release_published == 'true'
env:
ENV: ${{ steps.extract_environment.outputs.result }}
IMAGE_TAG: ${{ steps.semantic.outputs.new_release_version }}
run: |
docker-compose -f build.docker-compose.yml build
docker-compose -f build.docker-compose.yml push
- name: Create ZIP file to Deploy AWS Beanstalk
if: steps.semantic.outputs.new_release_published == 'true'
env:
ENV: ${{ steps.extract_environment.outputs.result }}
IMAGE_TAG: ${{ steps.semantic.outputs.new_release_version }}
run: |
sed -i -e "s/\${ENV}/$ENV/g" docker-compose.yml
sed -i -e "s/\${IMAGE_TAG}/$IMAGE_TAG/g" docker-compose.yml
zip deploy.zip docker-compose.yml
- name: Deploy AWS Beanstalk
if: steps.semantic.outputs.new_release_published == 'true'
env:
ENV: ${{ steps.extract_environment.outputs.result }}
AWS_REGION: us-east-1
APP_NAME: maestro
run: |
[[ -d .elasticbeanstalk/ ]] && rm -R .elasticbeanstalk/
printf "1\nn" | eb init $APP_NAME --region $AWS_REGION
eb use $APP_NAME-$ENV
echo -e "deploy:\n artifact: deploy.zip" >> .elasticbeanstalk/config.yml
eb deploy
+14 -2
View File
@@ -21,14 +21,26 @@ jobs:
env:
ENV: test
IMAGE_TAG: test
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
export ENV=test
docker-compose -f build.docker-compose.yml build
export IMAGE_TAG=test
export ACCOUNT_ID=test
docker-compose -f build.docker-compose.yml build --build-arg NPM_TOKEN=${NPM_TOKEN}
- name: Run Test
env:
ENV: test
IMAGE_TAG: test
ACCOUNT_ID: test
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
export ENV=test
docker-compose run --rm --entrypoint="npm run test" maestro
export IMAGE_TAG=test
docker-compose -f build.docker-compose.yml run -e NPM_TOKEN=${NPM_TOKEN} --rm --entrypoint="npm run test" maestro
- name: Remove Docker's Trash
continue-on-error: true
run: |
docker system prune
docker rmi -f $(docker images -aq)
+2 -5
View File
@@ -29,7 +29,7 @@ lerna-debug.log*
# IDE - VSCode
.vscode/*
!.vscode/settings.json
#!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
@@ -37,7 +37,4 @@ lerna-debug.log*
# Ignore .env files
*.env
# Elastic Beanstalk Files
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml
.env
+1
View File
@@ -0,0 +1 @@
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
+12 -11
View File
@@ -5,18 +5,18 @@
{
"preset": "eslint",
"releaseRules": [
{ "tag": "Fix", "release": "patch" },
{ "tag": "Feat", "release": "minor" },
{ "tag": "Update", "release": "minor" },
{ "tag": "Upgrade", "release": "minor" },
{ "tag": "Breaking", "release": "major" },
{ "tag": "Docs", "release": "patch" },
{ "tag": "Chore", "release": "minor" },
{ "tag": "Build", "release": "patch" },
{ "tag": "Refactor", "release": "minor" },
{ "tag": "Test", "release": "patch" },
{ "tag": "FIX", "release": "patch" },
{ "tag": "FEAT", "release": "minor" },
{ "tag": "UPDATE", "release": "minor" },
{ "tag": "UPGRADE", "release": "minor" },
{ "tag": "BREAKING", "release": "major" },
{ "tag": "DOCS", "release": "patch" },
{ "tag": "CHORE", "release": "minor" },
{ "tag": "BUILD", "release": "patch" },
{ "tag": "REFACTOR", "release": "minor" },
{ "tag": "TEST", "release": "patch" },
{ "tag": "CI", "release": "patch" },
{ "tag": "Perf", "release": "minor" }
{ "tag": "PERF", "release": "minor" }
]
}
],
@@ -26,6 +26,7 @@
"preset": "eslint"
}
],
"@semantic-release/npm",
"@semantic-release/github"
]
}
+7 -3
View File
@@ -1,12 +1,16 @@
FROM node:14 as packages
FROM node:14.15.4-alpine3.12 as packages
WORKDIR /packages
ARG NPM_TOKEN
COPY package.json .
COPY .npmrc .
RUN npm install
RUN rm -f ./.npmrc
FROM node:alpine
FROM node:14.15.4-alpine3.12
WORKDIR /app
COPY . /app/
ARG NPM_TOKEN
COPY --from=packages /packages/node_modules /app/node_modules
RUN npm run build
EXPOSE 3333
ENTRYPOINT npm run start
ENTRYPOINT npm run start
+35 -58
View File
@@ -1,73 +1,50 @@
# Maestro
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
</p>
<image src="./assets/maestro.svg" style="width:10rem">
<h1 align="center">Maestro</h1>
</p>
This is the Dadosfera´s gateway repository, it´s responsable for the communication between frontend application and Dadosfera´s mirosservices.
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
## 💻 Requirements
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
Before you start, make sure you have done the following steps:
## Description
* Installed Nodejs version 16.14.2
* Installed latest NPM version
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
## 🚀 Installing Maestro
First of all clone the repository:
* SSH:
```
git clone git@github.com:dadosfera/maestro.git
```
* HTTPS:
```
git clone git@github.com:dadosfera/maestro.git
```
## Running the app
## Enviroment variables
```bash
# development
$ npm run start
Here is a list of enviroment variables needed in order to run the application correctly.
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
ENV=
DUC_URL=
INFACTORY_URL=
TRFACTORY_URL=
OTFACTORY_URL=
PIFACTORY_URL=
JWT_PRIVATE_KEY=
AWS_IDENTITY_POOL_ID=
```
## Test
## Running Maestro
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
In order to run Maestro just run the following command:
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).
npm run start:dev
```
If everything is fine the Maestro will start and be ready to receive HTTP requests
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

+1 -1
View File
@@ -2,4 +2,4 @@ version: "3.8"
services:
maestro:
build: .
image: 468720548566.dkr.ecr.us-east-1.amazonaws.com/microservices/maestro_${ENV}:${IMAGE_TAG}
image: ${ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/microservices/maestro_${ENV}:${IMAGE_TAG}
+3 -1
View File
@@ -1,11 +1,13 @@
version: "3.8"
services:
maestro:
image: 468720548566.dkr.ecr.us-east-1.amazonaws.com/microservices/maestro_${ENV}:${IMAGE_TAG}
image: ${ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/microservices/maestro_${ENV}:${IMAGE_TAG}
container_name: maestro
restart: always
ports:
- 3333:3333
env_file:
- .env
node_exporter:
image: prom/node-exporter:v1.3.1
+10657 -1677
View File
File diff suppressed because it is too large Load Diff
+32 -25
View File
@@ -1,6 +1,6 @@
{
"name": "grpc-server-and-client-nestjs-micro-pattern",
"version": "1.0.1-alpha.1",
"version": "0.0.0",
"description": "",
"author": "",
"private": true,
@@ -21,48 +21,55 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@grpc/grpc-js": "^1.5.0",
"@grpc/grpc-js": "^1.5.10",
"@grpc/proto-loader": "^0.6.9",
"@nestjs/common": "^8.0.0",
"@nestjs/core": "^8.0.0",
"@nestjs/common": "^8.4.3",
"@nestjs/config": "^1.2.1",
"@nestjs/core": "^8.4.3",
"@nestjs/mapped-types": "*",
"@nestjs/microservices": "^8.2.4",
"@nestjs/platform-express": "^8.0.0",
"@nestjs/swagger": "^5.1.5",
"@nestjs/microservices": "^8.4.3",
"@nestjs/platform-express": "^8.4.3",
"@nestjs/schedule": "^1.1.0",
"@nestjs/swagger": "^5.2.1",
"@victorradael/protospack": "2.4.2-1",
"axios": "^0.25.0",
"dotenv": "^14.2.0",
"grpc": "^1.24.11",
"helmet": "^5.0.2",
"jsonwebtoken": "^8.5.1",
"jwk-to-pem": "^2.0.5",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"rxjs": "^7.5.5",
"swagger-ui-express": "^4.3.0"
},
"overrides":{
"busboy@<1.6.0":"1.6.0"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",
"@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0",
"@nestjs/cli": "^8.2.4",
"@nestjs/schematics": "^8.0.8",
"@nestjs/testing": "^8.4.3",
"@types/express": "^4.17.13",
"@types/jest": "27.0.2",
"@types/jsonwebtoken": "^8.5.8",
"@types/jwk-to-pem": "^2.0.1",
"@types/node": "^16.0.0",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"@types/node": "^16.11.26",
"@types/supertest": "^2.0.12",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.2.5",
"prettier": "^2.3.2",
"jest": "^27.5.1",
"nock": "^13.2.4",
"prettier": "^2.6.1",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "^27.0.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "^3.10.1",
"typescript": "^4.3.5"
"ts-jest": "^27.1.4",
"ts-loader": "^9.2.7",
"ts-node": "^10.7.0",
"tsconfig-paths": "^3.14.1",
"typescript": "^4.6.3"
},
"jest": {
"moduleFileExtensions": [
+101 -38
View File
@@ -1,44 +1,107 @@
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
import { InputGrpcClientModule } from './inputs/input-grpc-client.module';
import { UsersGrpcClientModule } from './users-grpc-client/users-grpc-client.module';
import { OutputsModule } from './outputs/outputs.module';
import { EnrichmentModule } from './enrichment/enrichment.module';
import { TransformationsModule } from './transformations/transformations.module';
import { PipelinesModule } from './pipelines/pipelines.module';
import { RestInputsModule } from './rest/rest-inputs/rest-inputs.module';
import { RestOutputsModule } from './rest/rest-outputs/rest-outputs.module';
import { RestEnrichmentsModule } from './rest/rest-enrichments/rest-enrichments.module';
import { RestTransformationsModule } from './rest/rest-transformations/rest-transformations.module';
import { RestPipelinesModule } from './rest/rest-pipelines/rest-pipelines.module';
import { RestUserModule } from './rest/rest-user/rest-user.module';
import { RestFactoryModule } from './rest/rest-factory/rest-factory.module';
import { LoggerMiddleware } from './middlewares/authentication';
import { RestInputsController } from './rest/rest-inputs/rest-inputs.controller';
import { RestOutputsController } from './rest/rest-outputs/rest-outputs.controller';
import { RestTransformationsController } from './rest/rest-transformations/rest-transformations.controller';
import { RestPipelinesController } from './rest/rest-pipelines/rest-pipelines.controller';
import { RestEnrichmentsController } from './rest/rest-enrichments/rest-enrichments.controller';
import { RestFactoryController } from './rest/rest-factory/rest-factory.controller';
import { HealthModule } from './health/health.module';
@Module({
imports: [
RestInputsModule, RestOutputsModule, RestEnrichmentsModule, RestTransformationsModule, RestPipelinesModule, RestUserModule, RestFactoryModule, HealthModule,
// InputGrpcClientModule,
//OutputsModule,
//EnrichmentModule,
//TransformationsModule,
//PipelinesModule
],
controllers: [],
providers: [],
})
export class AppModule implements NestModule{
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { ClientsModule } from '@nestjs/microservices';
import { ConfigModule } from '@nestjs/config';
import { LoggerMiddleware } from './middlewares/authentication';
import { InputsController } from './modules/inputs/inputs.controller';
import { TransformationsController } from './modules/transformations/transformations.controller';
import { OutputsController } from './modules/outputs/outputs.controllers';
import { PipelinesController } from './modules/pipelines/pipelines.controller';
import { AuthController } from './modules/auth/auth.controller';
import { HealthController } from './modules/health/health.controller';
import { InputsService } from './modules/inputs/inputs.service';
import { TransformationsService } from './modules/transformations/transformations.service';
import { OutputsService } from './modules/outputs/outputs.service';
import { PipelinesService } from './modules/pipelines/pipelines.service';
// import { AuthService } from './modules/auth/auth.service';
import { HealthService } from './modules/health/health.service';
import { InputsClientService } from './clients/inputs/client.service';
import { TransformationsClientService } from './clients/transformations/client.service';
import { OutputsClientService } from './clients/outputs/client.service';
import { PipelinesClientService } from './clients/pipelines/client.service';
import { AuthClientService } from './clients/auth/client.service';
import { OutputsClientConfiguration } from './clients/outputs/client.config';
import { TransformationsClientConfiguration } from './clients/transformations/client.config';
import { AuthClient } from './clients/auth/client.config';
import { InputsClientConfiguration } from './clients/inputs/client.config';
import { PipelinesClientConfiguration } from './clients/pipelines/client.config';
import { CatalogController } from './modules/catalog/catalog.controller';
import { CatalogService } from './modules/catalog/catalog.service';
const authClient = new AuthClient();
const inputClient = new InputsClientConfiguration();
const outputClient = new OutputsClientConfiguration();
const pipelineClient = new PipelinesClientConfiguration();
const transformationClient = new TransformationsClientConfiguration();
@Module({
controllers: [
InputsController,
TransformationsController,
OutputsController,
PipelinesController,
AuthController,
HealthController,
CatalogController,
],
providers: [
InputsService,
TransformationsService,
OutputsService,
PipelinesService,
// AuthService,
HealthService,
InputsClientService,
TransformationsClientService,
OutputsClientService,
PipelinesClientService,
AuthClientService,
CatalogService,
],
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
ClientsModule.register([
{
name: 'INPUTS_PACKAGE',
...inputClient.config(),
},
{
name: 'TRANSFORMATIONS_PACKAGE',
...transformationClient.config(),
},
{
name: 'OUTPUTS_PACKAGE',
...outputClient.config(),
},
{
name: 'AUTH_PACKAGE',
...authClient.config(),
},
{
name: 'PIPELINES_PACKAGE',
...pipelineClient.config(),
},
]),
],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes(RestInputsController,RestOutputsController,RestTransformationsController,RestPipelinesController,RestEnrichmentsController,RestFactoryController)
.forRoutes(
InputsController,
TransformationsController,
OutputsController,
PipelinesController,
CatalogController,
);
}
}
+25
View File
@@ -0,0 +1,25 @@
import { credentials } from '@grpc/grpc-js';
import { ClientOptions, Transport } from '@nestjs/microservices';
import { DucProtoFilePath, DucPackages } from '@victorradael/protospack';
export class AuthClient {
config(): ClientOptions {
return {
transport: Transport.GRPC,
options: {
url: process.env.DUC_URL,
package: DucPackages,
credentials: process.env.LOCAL_ENV
? undefined
: credentials.createSsl(),
protoPath: DucProtoFilePath,
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
}
}
+259
View File
@@ -0,0 +1,259 @@
import { OnModuleInit, Inject } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import {
DucServicesNames,
AuthServiceInterface,
AuthSignInRequest,
AuthRefreshAccessTokenRequest,
AuthConfirmationRequest,
AuthResendConfirmationCodeRequest,
AuthEnableTotpMfaRequest,
AuthDisableTotpMfaRequest,
AuthDismissTotpMfaRequest,
AuthVerifyTotpMfaRequest,
AuthChangePasswordRequest,
AuthResetPasswordRequest,
AuthVerifyResetPasswordCodeRequest,
AuthConfirmResetPasswordRequest,
} from '@victorradael/protospack';
export class AuthClientService implements OnModuleInit {
private authService: AuthServiceInterface;
constructor(
@Inject('AUTH_PACKAGE') private readonly grpcClient: ClientGrpc,
) {}
onModuleInit() {
this.authService = this.grpcClient.getService<AuthServiceInterface>(
DucServicesNames.AuthProtoService,
);
}
async signIn({ username, password, totp }: AuthSignInRequest): Promise<any> {
console.log('AuthClientService', 'SignIn');
return new Promise((resolve, reject) => {
this.authService.signIn({ username, password, totp }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async enableTotpMFA({
accessToken,
password,
}: AuthEnableTotpMfaRequest): Promise<any> {
console.log('AuthClientService', 'enableTotpMFA');
return new Promise((resolve, reject) => {
this.authService.enableTotpMfa({ accessToken, password }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async disableTotpMFA({
accessToken,
password,
}: AuthDisableTotpMfaRequest): Promise<any> {
console.log('AuthClientService', 'disableTotpMFA');
return new Promise((resolve, reject) => {
this.authService.disableTotpMfa({ accessToken, password }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async dismissTotpMFA({
accessToken,
}: AuthDismissTotpMfaRequest): Promise<any> {
console.log('AuthClientService', 'dismissTotpMFA');
return new Promise((resolve, reject) => {
this.authService.dismissTotpMfa({ accessToken }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async verifyTotp({
accessToken,
totp,
}: AuthVerifyTotpMfaRequest): Promise<any> {
console.log('AuthClientService', 'disableTotpMFA');
return new Promise((resolve, reject) => {
this.authService.verifyTotp({ accessToken, totp }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async confirmRegister({
username,
code,
}: AuthConfirmationRequest): Promise<any> {
console.log('AuthClientService', 'confirmRegister');
const tokens = await new Promise((resolve, reject) => {
this.authService.confirmRegister({ username, code }).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return tokens;
}
async resendeConfirmationCode({
username,
}: AuthResendConfirmationCodeRequest): Promise<any> {
console.log('AuthClientService', 'resendConfirmationCode');
const authResendConfirmationCodeRequestReturn = await new Promise(
(resolve, reject) => {
this.authService.resendConfirmationCode({ username }).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
},
)
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return authResendConfirmationCodeRequestReturn;
}
async refreshAccessToken({
refreshToken,
}: AuthRefreshAccessTokenRequest): Promise<any> {
console.log('AuthClientService', 'RefreshAccessToken');
return new Promise((resolve, reject) => {
this.authService.refreshAccessToken({ refreshToken }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async changePassword({
accessToken,
oldPassword,
newPassword,
}: AuthChangePasswordRequest): Promise<any> {
console.log('AuthClientService', 'ChangePassword');
return new Promise((resolve, reject) => {
this.authService
.changePassword({
accessToken,
oldPassword,
newPassword,
})
.subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async resetPassword({ username }: AuthResetPasswordRequest): Promise<any> {
console.log('AuthClientService', 'resetPassword');
return new Promise((resolve, reject) => {
this.authService.resetPassword({ username }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async verifyResetPasswordCode({
username,
code,
}: AuthVerifyResetPasswordCodeRequest): Promise<any> {
console.log('AuthClientService', 'verifyResetPasswordCode');
return new Promise((resolve, reject) => {
this.authService.verifyResetPasswordCode({ username, code }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
async confirmResetPassword({
username,
code,
newPassword,
}: AuthConfirmResetPasswordRequest): Promise<any> {
console.log('AuthClientService', 'confirmResetPassword');
return new Promise((resolve, reject) => {
this.authService
.confirmResetPassword({ username, code, newPassword })
.subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
});
}
}
+25
View File
@@ -0,0 +1,25 @@
import { credentials } from '@grpc/grpc-js';
import { ClientOptions, Transport } from '@nestjs/microservices';
import { InputPackages, InputProtoFilePath } from '@victorradael/protospack';
export class InputsClientConfiguration {
config(): ClientOptions {
return {
transport: Transport.GRPC,
options: {
url: process.env.INFACTORY_URL,
package: InputPackages,
credentials: process.env.LOCAL_ENV
? undefined
: credentials.createSsl(),
protoPath: InputProtoFilePath,
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
}
}
+224
View File
@@ -0,0 +1,224 @@
import { OnModuleInit, Inject } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import {
InputCreateResponse,
InputCreateS3Request,
InputNewCreateRequest,
InputService,
TestConnectionGetColumnsRequest,
TestConnectionRequest,
} from '@victorradael/protospack';
import {
objectCamelToSnake,
objectSnakeToCamel,
} from 'src/utils/CaseConverter';
import { IIdRequest, UpdateInputRequest } from './interfaces';
export class InputsClientService implements OnModuleInit {
private inputService: InputService;
constructor(
@Inject('INPUTS_PACKAGE') private readonly grpcClient: ClientGrpc,
) {}
onModuleInit() {
this.inputService =
this.grpcClient.getService<InputService>('InputService');
}
async create(createInputDto: InputNewCreateRequest) {
console.log('InputClientService', 'Create');
const createInputResponse = await new Promise((resolve, reject) => {
this.inputService
.NewCreate(objectSnakeToCamel(createInputDto))
.subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
}).catch((err) => {
throw new Error(err);
});
return createInputResponse;
}
async createS3Inputs(createInputDto: InputCreateS3Request) {
console.log('InputClientService', 'Create');
const createInputResponse = await new Promise((resolve, reject) => {
this.inputService.CreateS3(objectSnakeToCamel(createInputDto)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return createInputResponse;
}
async findOne(data: IIdRequest) {
console.log('InputClientService', 'FindOne');
const findOneInputResponse = await new Promise((resolve, reject) => {
this.inputService.FindOne(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return findOneInputResponse;
}
async findAll(data) {
console.log('InputClientService', 'FindAll');
const findAllInputResponse = await new Promise((resolve, reject) => {
this.inputService.FindAll(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return findAllInputResponse;
}
async update(updateInputDTO: UpdateInputRequest) {
console.log('InputClientService', 'Update');
const updateInputResponse = await new Promise((resolve, reject) => {
this.inputService.Update(objectSnakeToCamel(updateInputDTO)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return updateInputResponse;
}
async remove(idRequest: IIdRequest) {
console.log('InputClientService', 'Remove');
const removeInputResponse = await new Promise((resolve, reject) => {
this.inputService.Remove(objectSnakeToCamel(idRequest)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return removeInputResponse;
}
async testConnection(data: TestConnectionRequest) {
console.log('InputClientService', 'TestConnection');
const testConnectionResponse = await new Promise((resolve, reject) => {
this.inputService.NewTestConnection(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return testConnectionResponse;
}
async getColumns(data: TestConnectionGetColumnsRequest) {
console.log('InputClientService', 'TestConnection/Get-Columns');
const getColumnsResponse = await new Promise((resolve, reject) => {
this.inputService.GetColumns(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return getColumnsResponse;
}
}
+62
View File
@@ -0,0 +1,62 @@
interface Values {
jdbc_user: string;
jdbc_password: string;
database: string;
endpoint: string;
tables: string[];
port: string;
engine: string;
schema: string;
}
interface Cron {
hours: string[];
hour_interval: boolean;
hour_resourse: boolean;
hour_resourse_value: number;
month_day: string[];
month_day_interval: boolean;
month_day_resourse: boolean;
month_day_resourse_value: number;
month: string[];
month_interval: boolean;
month_resourse: boolean;
month_resourse_value: number;
week_days: string[];
week_days_interval: boolean;
week_days_resourse: boolean;
week_days_resourse_value: number;
}
export interface Info {
costumer_id: string;
user_id: string;
}
export interface ICreateInputRequest {
cron: string;
name: string;
plugin: string;
values: Values;
operation: string;
info: Info;
}
export interface IIdRequest {
id: string;
info: Info;
}
export interface UpdateInputRequest {
id: string;
cron: string;
name: string;
plugin: string;
values: Values;
operation: string;
info: Info;
}
export interface ITestConnectionRequest {
plugin: string;
values: Values;
}
+24
View File
@@ -0,0 +1,24 @@
import { OutputPackages, OutputProtoFilePath } from '@victorradael/protospack';
import { ClientOptions, Transport } from '@nestjs/microservices';
import { credentials } from '@grpc/grpc-js';
export class OutputsClientConfiguration {
config(): ClientOptions {
return {
transport: Transport.GRPC,
options: {
url: process.env.OTFACTORY_URL,
package: OutputPackages,
credentials: process.env.LOCAL_ENV
? undefined
: credentials.createSsl(),
protoPath: OutputProtoFilePath,
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
}
}
+160
View File
@@ -0,0 +1,160 @@
import { Controller, Inject, OnModuleInit } from '@nestjs/common';
import { ClientGrpc, Payload } from '@nestjs/microservices';
import {
OutputServicesNames,
OutputsServiceInterface,
} from '@victorradael/protospack';
import {
objectCamelToSnake,
objectSnakeToCamel,
} from 'src/utils/CaseConverter';
import {
ICreateOutputRequest,
IIdRequest,
IOutputUpdateRequest,
} from './interfaces';
@Controller('output')
export class OutputsClientService implements OnModuleInit {
private outputService: OutputsServiceInterface;
constructor(
@Inject('OUTPUTS_PACKAGE') private readonly grpcClient: ClientGrpc,
) {}
onModuleInit() {
this.outputService = this.grpcClient.getService<OutputsServiceInterface>(
OutputServicesNames.OutputService,
);
}
async create(@Payload() createOutputDto: ICreateOutputRequest) {
console.log('OutputClientService', 'Create');
const createOutputResponse = await new Promise((resolve, reject) => {
this.outputService.Create(objectSnakeToCamel(createOutputDto)).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
const convertedItem = objectCamelToSnake(createOutputResponse['output']);
createOutputResponse['output'] = convertedItem;
return createOutputResponse;
}
async findAll(data) {
console.log('OutputClientService', 'FindAll');
const findAllOutputResponse = await new Promise((resolve, reject) => {
this.outputService.FindAll(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
const convertedOutputs = findAllOutputResponse['outputs'].map((ot) => {
return objectCamelToSnake(ot);
});
return { outputs: convertedOutputs };
}
async findOne(data: IIdRequest) {
console.log('OutputClientService', 'FindOne');
const findOneOutputResponse = await new Promise((resolve, reject) => {
this.outputService.FindOne(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return objectCamelToSnake(findOneOutputResponse);
}
async update(updateOutPutDTO: IOutputUpdateRequest) {
console.log('OutputClientService', 'Update');
const updateOutputResponse = await new Promise((resolve, reject) => {
this.outputService.Update(objectSnakeToCamel(updateOutPutDTO)).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return objectCamelToSnake(updateOutputResponse);
}
async remove(data: IIdRequest) {
console.log('OutputClientService', 'Remove');
const removeOutputResponse = await new Promise((resolve, reject) => {
this.outputService.Remove(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return removeOutputResponse;
}
}
+29
View File
@@ -0,0 +1,29 @@
export interface ICreateOutputRequest {
operation: string;
name: string;
plugin: string;
values: Values;
}
export interface Values {
prefix: string;
}
interface Info {
user_id: string;
customer_id: string;
}
export interface IIdRequest {
id: string;
info: Info;
}
export interface IOutputUpdateRequest {
id: string;
operation: string;
values: Values;
plugin: string;
name: string;
info: Info;
}
+27
View File
@@ -0,0 +1,27 @@
import { ClientOptions, Transport } from '@nestjs/microservices';
import {
PipelinePackages,
PipelineProtoFilePath,
} from '@victorradael/protospack';
import { credentials } from '@grpc/grpc-js';
export class PipelinesClientConfiguration {
config(): ClientOptions {
return {
transport: Transport.GRPC,
options: {
url: process.env.PIFACTORY_URL,
package: PipelinePackages,
credentials: process.env.LOCAL_ENV
? undefined
: credentials.createSsl(),
protoPath: PipelineProtoFilePath,
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
}
}
+249
View File
@@ -0,0 +1,249 @@
import { Inject, OnModuleInit } from '@nestjs/common';
import { ClientGrpc, Payload } from '@nestjs/microservices';
import {
PipelineServicesNames,
PipelinesServiceInterface,
} from '@victorradael/protospack';
import {
objectCamelToSnake,
objectSnakeToCamel,
} from 'src/utils/CaseConverter';
import {
ICreatePipelineDto,
IGetPipelineLogsRequest,
IIdRequest,
IUpdatePipelineRequest,
} from './interfaces';
export class PipelinesClientService implements OnModuleInit {
private pipelineService: PipelinesServiceInterface;
constructor(
@Inject('PIPELINES_PACKAGE') private readonly grpcClient: ClientGrpc,
) {}
onModuleInit() {
this.pipelineService =
this.grpcClient.getService<PipelinesServiceInterface>(
PipelineServicesNames.PipelineService,
);
}
async create(@Payload() createPipelineDto: ICreatePipelineDto) {
console.log('PipelinesClientService', 'Create');
const createPipelineResponse = await new Promise((resolve, reject) => {
this.pipelineService
.Create(objectSnakeToCamel(createPipelineDto))
.subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return createPipelineResponse;
}
async findAll(data: IIdRequest) {
console.log('PipelinesClientService', 'FindAll');
const findAllPipelineResponse = await new Promise((resolve, reject) => {
this.pipelineService.FindAll(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(x.pipelines);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return findAllPipelineResponse;
}
async findOne(data: IIdRequest) {
console.log('PipelinesClientService', 'FindOne');
const findOnePipelineResponse = await new Promise((resolve, reject) => {
this.pipelineService.FindOne(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return findOnePipelineResponse;
}
async update(UpdatePipelineRequest: IUpdatePipelineRequest) {
console.log('PipelinesClientService', 'Update');
const updatePipelineResponse = await new Promise((resolve, reject) => {
this.pipelineService
.Update(objectSnakeToCamel(UpdatePipelineRequest))
.subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return updatePipelineResponse;
}
async remove(data: IIdRequest) {
console.log('PipelinesClientService', 'Remove');
const removePipelineResponse = await new Promise((resolve, reject) => {
this.pipelineService.remove(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(objectCamelToSnake(x));
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return removePipelineResponse;
}
async getPipelineLogsMessages(data: IGetPipelineLogsRequest) {
console.log('PipelinesClientService', 'GetPipelineLogsMessages');
const logsPipelineResponse = await new Promise((resolve, reject) => {
this.pipelineService.getPipelineLogs(data).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return logsPipelineResponse;
}
async getPipelineStatus(data) {
console.log('PipelinesClientService', 'GetPipelineStatus');
const statusPipelineResponse = await new Promise((resolve, reject) => {
this.pipelineService
.getPipelineStatus(objectSnakeToCamel(data))
.subscribe({
next(x) {
const statusArray = x.status.sort((a, b) => {
if (a.id < b.id) {
return 1;
} else {
return -1;
}
});
resolve({ status: statusArray });
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return statusPipelineResponse;
}
async runPipeline({ id, info }: IIdRequest) {
console.log('PipelinesClientService', 'RunPipeline');
const statusPipelineResponse = await new Promise((resolve, reject) => {
this.pipelineService
.triggerPipeline(objectSnakeToCamel({ id, info }))
.subscribe({
next(x) {
if (x.status == false) {
reject(
'This pipeline is not ready yet to execute, Try again later!',
);
}
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return statusPipelineResponse;
}
}
+39
View File
@@ -0,0 +1,39 @@
export interface ICreatePipelineDto {
input: IdRequest;
transformations: IdRequest[];
output: IdRequest;
tags: string[];
name: string;
description: string;
info: Info;
}
export interface Info {
customer_id: sting;
user_id: string;
}
export interface IdRequest {
id: string;
}
export interface IIdRequest {
id: string;
info: Info;
}
export interface IUpdatePipelineRequest {
input: IdRequest;
transformations: IdRequest[];
output: IdRequest;
tags: string[];
name: string;
description: string;
id: string;
info: Info;
}
export interface IGetPipelineLogsRequest {
id: string;
details: string;
}
@@ -0,0 +1,25 @@
import { ClientOptions, Transport } from '@nestjs/microservices';
import {
TransformationPackages,
TransformationProtoFilePath,
} from '@victorradael/protospack';
import { credentials } from '@grpc/grpc-js';
export class TransformationsClientConfiguration {
config(): ClientOptions {
return {
transport: Transport.GRPC,
options: {
url: process.env.INFACTORY_URL,
package: TransformationPackages,
credentials: credentials.createSsl(),
protoPath: TransformationProtoFilePath,
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
}
}
@@ -0,0 +1,173 @@
import { Controller, Inject, OnModuleInit, Post } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { TransformationsServiceInterface } from '@victorradael/protospack';
import {
objectCamelToSnake,
objectSnakeToCamel,
} from 'src/utils/CaseConverter';
import { ICreateTransformationsRequest, IIdRequest } from './interfaces';
@Controller('transformation')
export class TransformationsClientService implements OnModuleInit {
private transformationService: TransformationsServiceInterface;
constructor(
@Inject('TRANSFORMATIONS_PACKAGE') private readonly grpcClient: ClientGrpc,
) {}
onModuleInit() {
this.transformationService =
this.grpcClient.getService<TransformationsServiceInterface>(
'TransformationService',
);
}
@Post()
async create(createTransformationsDto: ICreateTransformationsRequest) {
console.log('TransformationClientService', 'Create');
const createTransformationResponse = await new Promise(
(resolve, reject) => {
this.transformationService
.Create(objectSnakeToCamel(createTransformationsDto))
.subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
},
)
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
const convertedTransforms = createTransformationResponse[
'transformations'
].map((tr) => {
return objectCamelToSnake(tr);
});
return { transformations: convertedTransforms };
}
async findAll(data) {
console.log('TransformationClientService', 'FindAll');
const findAllTransformationResponse = await new Promise(
(resolve, reject) => {
this.transformationService.FindAll(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
},
)
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
const convertedTransforms = findAllTransformationResponse[
'transformations'
].map((tr) => {
return objectCamelToSnake(tr);
});
return { transformations: convertedTransforms };
}
async findOne(data: IIdRequest) {
console.log('TransformationClientService', 'FindOne');
const findOneTransformationResponse = await new Promise(
(resolve, reject) => {
this.transformationService.FindOne(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
},
)
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return objectCamelToSnake(findOneTransformationResponse);
}
async update(updateTransformationDTO) {
console.log('TransformationClientService', 'Update');
const updateTransformationResponse = await new Promise(
(resolve, reject) => {
this.transformationService
.Update(objectSnakeToCamel(updateTransformationDTO))
.subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
},
)
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return objectCamelToSnake(updateTransformationResponse);
}
async remove(data: IIdRequest) {
console.log('TransformationClientService', 'Remove');
const removeTransformationResponse = await new Promise(
(resolve, reject) => {
this.transformationService.Remove(objectSnakeToCamel(data)).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
complete() {
console.log('done');
},
});
},
)
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return objectCamelToSnake(removeTransformationResponse);
}
}
+37
View File
@@ -0,0 +1,37 @@
export interface ICreateTransformationsRequest {
transformations: Transformation[];
info: Info;
}
interface Param {
base_column: string;
column_name: string;
n_digits: number;
start_index: number;
randbelow: number;
const: string;
}
export interface Info {
customer_id: string;
user_id: string;
}
interface Transformation {
created_at: string;
id: string;
client_id: string;
type: string;
params: Param[];
input_source: string;
table: string;
}
export interface IIdRequest {
id: string;
info: Info;
}
export interface IUpdateTransformationRequest {
transformation: Transformation;
info: Info;
}
-17
View File
@@ -1,17 +0,0 @@
import { join } from 'path';
import { ClientOptions, Transport } from '@nestjs/microservices';
export const GrpcClientConfiguration: ClientOptions = {
transport: Transport.GRPC,
options: {
//url: `${process.env.USERS_SVC_URL}:${process.env.USERS_SVC_PORT}`,
url: `127.0.0.1:50053`,
package: 'enrichment',
protoPath: join(__dirname, '..', 'proto', 'enrichment.proto'),
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
@@ -1,6 +0,0 @@
export class CreateEnrichmentDto {
type:string;
columns:string[]
}
@@ -1,6 +0,0 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreateEnrichmentDto } from './create-enrichment.dto';
export class UpdateEnrichmentDto extends PartialType(CreateEnrichmentDto) {
}
@@ -1,20 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EnrichmentController } from './enrichment.controller';
import { EnrichmentsService } from './enrichment.service';
describe('EnrichmentController', () => {
let controller: EnrichmentController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [EnrichmentController],
providers: [EnrichmentsService],
}).compile();
controller = module.get<EnrichmentController>(EnrichmentController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
-60
View File
@@ -1,60 +0,0 @@
import {
Controller,
Delete,
Get,
OnModuleInit,
Param,
Post,
Put,
} from '@nestjs/common';
import { Client, ClientGrpc, Payload } from '@nestjs/microservices';
import { EnrichmentsService } from './enrichment.service';
import { CreateEnrichmentDto } from './dto/create-enrichment.dto';
import { UpdateEnrichmentDto } from './dto/update-enrichment.dto';
import { ApiTags } from '@nestjs/swagger';
import { GrpcClientConfiguration } from './config/grpc-client';
@ApiTags('enrichments')
@Controller('enrichment')
export class EnrichmentController implements OnModuleInit {
@Client(GrpcClientConfiguration)
private enrichmentServiceClient: ClientGrpc;
private enrichmentService: EnrichmentsService;
onModuleInit() {
this.enrichmentService =
this.enrichmentServiceClient.getService<EnrichmentsService>(
'EnrichmentService',
);
}
@Post()
create(@Payload() createEnrichmentDto: CreateEnrichmentDto) {
return this.enrichmentService.create(createEnrichmentDto);
}
@Get()
list() {
return this.enrichmentService.list();
}
@Get(':id')
show(@Param() id: string) {
return this.enrichmentService.show(id);
}
@Put(':id')
update(
@Param() id: string,
@Payload() updateEnrichmentDto: UpdateEnrichmentDto,
) {
return this.enrichmentService.update(id, updateEnrichmentDto);
}
@Delete(':id')
remove(@Param() id: string) {
return this.enrichmentService.remove(id);
}
}
-9
View File
@@ -1,9 +0,0 @@
import { Module } from '@nestjs/common';
import { EnrichmentsService } from './enrichment.service';
import { EnrichmentController } from './enrichment.controller';
@Module({
controllers: [EnrichmentController],
providers: [EnrichmentsService],
})
export class EnrichmentModule {}
-18
View File
@@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EnrichmentsService } from './enrichment.service';
describe('EnrichmentService', () => {
let service: EnrichmentsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [EnrichmentsService],
}).compile();
service = module.get<EnrichmentsService>(EnrichmentsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
-26
View File
@@ -1,26 +0,0 @@
import { Injectable } from '@nestjs/common';
import { CreateEnrichmentDto } from './dto/create-enrichment.dto';
import { UpdateEnrichmentDto } from './dto/update-enrichment.dto';
@Injectable()
export class EnrichmentsService {
create(createEnrichmentDto: CreateEnrichmentDto) {
return 'This action adds a new enrichment';
}
list() {
return `This action returns all enrichment`;
}
show(id: string) {
return `This action returns a #${id} enrichment`;
}
update(id: string, updateEnrichmentDto: UpdateEnrichmentDto) {
return `This action updates a #${id} enrichment`;
}
remove(id: string) {
return `This action removes a #${id} enrichment`;
}
}
@@ -1,8 +0,0 @@
export class Enrichment {
id:string;
type:string;
columns:string[]
}
-43
View File
@@ -1,43 +0,0 @@
syntax = "proto3";
package enrichment;
import "google/protobuf/timestamp.proto";
service EnrichmentService {
rpc Create(CreateEnrichmentRequest) returns (Enrichment) {}
rpc Show(IdRequest) returns (Enrichment) {}
rpc List(Empty) returns (ListResponse){}
rpc Update(UpdateEnrichmentRequest) returns (Enrichment){}
rpc Remove(IdRequest) returns (Empty){}
}
message Empty {}
message IdRequest{
string id = 1;
}
message UpdateEnrichmentRequest{
string id = 1;
string type = 2;
repeated string columns = 3;
}
message Enrichment {
string id = 1;
string type = 2;
repeated string columns = 3;
}
message CreateEnrichmentRequest {
string type = 1;
repeated string columns = 2;
}
message ListResponse {
repeated Enrichment enrichments = 2;
}
+7
View File
@@ -0,0 +1,7 @@
import { HttpExceptionFilter } from './http-exception.filter';
describe('HttpExceptionFilter', () => {
it('should be defined', () => {
expect(new HttpExceptionFilter()).toBeDefined();
});
});
+24
View File
@@ -0,0 +1,24 @@
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response.status(status).json({
status_code: status,
timestamp: new Date().toISOString(),
path: request.url,
method: request.method,
});
}
}
-1
View File
@@ -1 +0,0 @@
export class Health {}
-9
View File
@@ -1,9 +0,0 @@
import { Module } from '@nestjs/common';
import { HealthService } from './health.service';
import { HealthController } from './health.controller';
@Module({
controllers: [HealthController],
providers: [HealthService],
})
export class HealthModule {}
-17
View File
@@ -1,17 +0,0 @@
import { join } from 'path';
import { ClientOptions, Transport } from '@nestjs/microservices';
export const GrpcClientConfiguration: ClientOptions = {
transport: Transport.GRPC,
options: {
//url: `${process.env.USERS_SVC_URL}:${process.env.USERS_SVC_PORT}`,
url: `127.0.0.1:50052`,
package: 'input',
protoPath: join(__dirname, '..', 'proto', 'input.proto'),
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
@@ -1,13 +0,0 @@
export class CreateInputGrpcClientDto {
cron:string;
name:string;
plugin:string;
values:string;
operation:string;
}
@@ -1,5 +0,0 @@
export class TestConnectionDTO{
values:string;
plugin:string;
}
@@ -1,6 +0,0 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreateInputGrpcClientDto } from './create-input-grpc-client.dto';
export class UpdateInputGrpcClientDto extends PartialType(
CreateInputGrpcClientDto,
) {}
@@ -1,14 +0,0 @@
export class InputGrpcClient {
id:string;
cron:string;
name:string;
plugin:string;
values:string;
operation:string;
}
@@ -1,63 +0,0 @@
import {
Get,
Post,
Controller,
Delete,
OnModuleInit,
Put,
Param
} from '@nestjs/common';
import { Client, ClientGrpc, Payload } from '@nestjs/microservices';
import { CreateInputGrpcClientDto } from './dto/create-input-grpc-client.dto';
import { UpdateInputGrpcClientDto } from './dto/update-input-grpc-client.dto';
import { InputGrpcClientService } from './input-grpc-client.service';
import { GrpcClientConfiguration } from './config/grpc-client';
import { TestConnectionDTO } from './dto/test-connection-grpc-client.dto';
import { ApiTags } from '@nestjs/swagger';
@Controller('grpc/input')
export class InputGrpcClientController implements OnModuleInit {
@Client(GrpcClientConfiguration)
private inputServiceClient: ClientGrpc;
private inputService: InputGrpcClientService;
onModuleInit() {
this.inputService =
this.inputServiceClient.getService<InputGrpcClientService>('InputService');
}
@Post()
async create(@Payload() createInputDto: CreateInputGrpcClientDto) {
return this.inputService.create(createInputDto);
}
@Get()
list() {
return this.inputService.list();
}
@Get(':id')
show(@Param() id: string) {
return this.inputService.show(id);
}
@Put(':id')
update(
@Payload() updateInputDto: UpdateInputGrpcClientDto,
@Param() id: string,
) {
return this.inputService.update(id, updateInputDto);
}
@Delete(':id')
remove(@Param() id: string) {
return this.inputService.remove(id);
}
@Get('/test-connection')
testConnection(@Payload() testConnectionDTO:TestConnectionDTO){
return this.inputService.testConnection(testConnectionDTO)
}
}
-13
View File
@@ -1,13 +0,0 @@
import { Module } from '@nestjs/common';
import { InputGrpcClientService } from './input-grpc-client.service';
import { InputGrpcClientController } from './input-grpc-client.controller';
// import { InputRestClientController } from './input-rest-client.controller';
@Module({
controllers: [
InputGrpcClientController,
// InputRestClientController
],
providers: [InputGrpcClientService],
})
export class InputGrpcClientModule {}
@@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { InputGrpcClientService } from './input-grpc-client.service';
describe('InputGrcpClientService', () => {
let service: InputGrpcClientService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [InputGrpcClientService],
}).compile();
service = module.get<InputGrpcClientService>(InputGrpcClientService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
-31
View File
@@ -1,31 +0,0 @@
import { Injectable } from '@nestjs/common';
import { CreateInputGrpcClientDto } from './dto/create-input-grpc-client.dto';
import { TestConnectionDTO } from './dto/test-connection-grpc-client.dto';
import { UpdateInputGrpcClientDto } from './dto/update-input-grpc-client.dto';
@Injectable()
export class InputGrpcClientService {
create(createInputGrcpClientDto: CreateInputGrpcClientDto) {
return 'This action adds a new InputGrcpClient';
}
list() {
return `This action returns all InputGrcpClient`;
}
show(id: string) {
return `This action returns a #${id} InputGrcpClient`;
}
update(id: string, updateInputGrcpClientDto: UpdateInputGrpcClientDto) {
return `This action updates a #${id} InputGrcpClient`;
}
remove(id: string) {
return `This action removes a #${id} InputGrcpClient`;
}
testConnection(testConnectionDTO:TestConnectionDTO){
return `This action tests a given connection`;
}
}
@@ -1,71 +0,0 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Redirect } from '@nestjs/common';
import { Payload } from '@nestjs/microservices';
import axios from 'axios';
import { Console } from 'console';
import { CreateInputGrpcClientDto } from './dto/create-input-grpc-client.dto';
import { UpdateInputGrpcClientDto } from './dto/update-input-grpc-client.dto';
@Controller('input')
export class InputRestClientController {
@Get('/test-connection/')
async testConnection(){
console.log(process.env.DEV_URL+`/test-connection`, "ON TEST CONNECTION ROUTE")
await axios.get(process.env.DEV_URL+`/test-connection`).then( (response) => {
return response
})
}
@Post()
async create(@Body() createInputDto: CreateInputGrpcClientDto){
console.log(createInputDto)
console.log(process.env.DEV_URL+`/input`, "ON CREATE ROUTE")
await axios.post(process.env.DEV_URL+'/input',createInputDto).then( (response) => {
return response
})
}
@Get()
async list(){
console.log(process.env.DEV_URL+`/input`, "ON GET ROUTE")
await axios.get(process.env.DEV_URL+`/input`).then( (response) => {
return response
})
}
@Get('/:id')
async show(@Param() id: string){
console.log(process.env.DEV_URL+`/input/${id}`, "ON SHOW ROUTE")
await axios.get(process.env.DEV_URL+`/input/${id}`).then( (response) => {
return response
})
}
@Put(':id')
async update(
@Payload() updateInputDto: UpdateInputGrpcClientDto,
@Param() id: string,
){
console.log(process.env.DEV_URL+`/input/${id}`, "ON UPDATE ROUTE")
await axios.put(process.env.DEV_URL+`input/${id}`,updateInputDto).then( (response) => {
return response
})
}
@Delete(':id')
async delete(@Param() id: string){
console.log(process.env.DEV_URL+`/input/${id}`, "ON DELETE ROUTE")
await axios.delete(process.env.DEV_URL+`/input/${id}`).then( (response) => {
return response
})
}
}
-65
View File
@@ -1,65 +0,0 @@
syntax = "proto3";
package input;
import "google/protobuf/timestamp.proto";
service InputService {
rpc Create(CreateInputRequest) returns (Input) {}
rpc Show(IdRequest) returns (Input) {}
rpc List(Empty) returns (ListResponse){}
rpc Update(UpdateInputRequest) returns (Input){}
rpc Remove(IdRequest) returns (Empty){}
rpc TestConnection(TestConnectionRequest) returns (TestConnectionResponse){}
}
message Empty {}
message IdRequest{
string id = 1;
}
message UpdateInputRequest{
string id = 1;
string cron = 2;
string name = 3;
string plugin = 4;
string values = 5;
string operation = 6;
}
message Input {
string id = 1;
string cronFormated = 2;
string name = 3;
string plugin = 4;
string values = 5;
string operation = 6;
}
message CreateInputRequest {
string cron = 1;
string name = 2;
string plugin = 3;
string values = 4;
string operation = 5;
}
message ListResponse {
repeated Input inputs = 1;
}
message TestConnectionRequest{
string values = 1;
string plugin = 2;
}
message TestConnectionResponse{
// nao sei como vai ser a resposta
bool respose = 1;
}
+12 -3
View File
@@ -1,12 +1,21 @@
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { writeFileSync } from 'fs';
import helmet from 'helmet';
import { AppModule } from './app.module';
import { config } from 'dotenv';
config();
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const app = await NestFactory.create(AppModule, {
cors: {
origin: '*',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
preflightContinue: false,
optionsSuccessStatus: 204,
},
});
app.use(helmet());
const config = new DocumentBuilder()
.setTitle('Maestro Grpc Documentation')
+123 -19
View File
@@ -1,30 +1,134 @@
import { Request, Response, NextFunction } from 'express';
import axios from 'axios';
import { NestMiddleware } from '@nestjs/common';
import {
ForbiddenException,
InternalServerErrorException,
NestMiddleware,
UnauthorizedException,
UseFilters,
} from '@nestjs/common';
import jwkToPem from 'jwk-to-pem';
import { decode, verify } from 'jsonwebtoken';
import { HttpExceptionFilter } from '../error/http-exception.filter';
export class LoggerMiddleware implements NestMiddleware{
@UseFilters(new HttpExceptionFilter())
export class LoggerMiddleware implements NestMiddleware {
use = async (request: Request, response: Response, next: NextFunction) => {
const idToken = request.get('Dadosfera-User');
const accessToken = request.get('Authorization');
const privateKey = process.env.JWT_PRIVATE_KEY;
let requiredRoute = '';
const requiredMethod = request.method.trim();
if (request.route.path.split('/').length >= 2) {
requiredRoute = request.route.path.split('/')[1].trim();
}
verify(idToken, privateKey, (err) => {
if (err) {
throw new UnauthorizedException();
}
});
const jwtDecoded: any = decode(idToken);
use = async (
request: Request,
response: Response,
next: NextFunction
) => {
const permissions = jwtDecoded.user.permissions;
try {
const verify_response = await axios.post(
`${process.env.DEV_URL}/user/verify`,
{ "token":request.get('Authorization')}
).then(response =>{
if(response.data.message == "Success"){
next()
}
})
const clienId = jwtDecoded.user.customerId;
const customer = jwtDecoded.user.customer;
const userId = jwtDecoded.user.id;
await verifyToken(accessToken);
} catch (error) {
response.status(401).send({ message: 'Authentication Failed!' });
}
let havePermission = false;
const permission = permissions.find((permission) => {
permission = permission.split('/');
const method = permission[0].trim();
const route = permission[1].trim();
if (method === requiredMethod && route === requiredRoute) {
return permission;
}
});
if (permission) {
havePermission = true;
}
if (havePermission) {
request.body.info = {
customer_id: clienId,
user_id: userId,
customer,
};
next();
} else {
throw new ForbiddenException();
}
};
}
let pems: { [key: string]: Record<string, unknown> }[];
const setUp = async (region: string, id: string) => {
const URL = `https://cognito-idp.${region}.amazonaws.com/${id}/.well-known/jwks.json`;
try {
const response = await axios.get(URL);
if (response.status !== 200) {
throw new InternalServerErrorException();
}
const data = await response.data;
const { keys } = data;
pems = keys.map((key: any) => {
const modulus = key.n;
const exponent = key.e;
const keyType = key.kty;
const jwk = { kty: keyType, n: modulus, e: exponent };
const pem = jwkToPem(jwk);
const keyId = key.kid;
return { [keyId]: pem };
});
} catch (error) {
// console.log(error);
// console.log('Error! Unable to download JWKs');
}
};
const verifyToken = async (accessToken: string) => {
const awsRegion = process.env.AWS_REGION;
const awsPoolId = process.env.AWS_IDENTITY_POOL_ID;
try {
await setUp(awsRegion, awsPoolId);
if (!accessToken) {
throw new UnauthorizedException();
}
const user: any = decode(accessToken, { complete: true });
if (user === null) {
throw new UnauthorizedException();
}
const { kid } = user.header;
const pem = pems.filter((item: any) => item[kid]);
const pemValue: any = pem[0][kid];
if (!pem) {
throw new UnauthorizedException();
}
verify(accessToken, pemValue, (err: any) => {
if (err) {
throw new UnauthorizedException();
}
return;
});
} catch (error) {
throw new UnauthorizedException();
}
};
+227
View File
@@ -0,0 +1,227 @@
import {
Body,
Controller,
Headers,
Post,
HttpCode,
HttpStatus,
} from '@nestjs/common';
import {
AuthSignInRequest,
AuthRefreshAccessTokenRequest,
AuthEnableTotpMfaRequest,
AuthDisableTotpMfaRequest,
AuthVerifyTotpMfaRequest,
AuthChangePasswordRequest,
AuthResetPasswordRequest,
AuthVerifyResetPasswordCodeRequest,
AuthConfirmResetPasswordRequest,
} from '@victorradael/protospack';
import { AuthClientService } from 'src/clients/auth/client.service';
import ErrorBuilder from '../../utils/ErrorBuilder';
@Controller('auth')
export class AuthController {
constructor(private authClient: AuthClientService) {}
// DEPRECADO!
@Post()
@HttpCode(HttpStatus.OK)
async signIn_old(@Body() body: AuthSignInRequest) {
console.log(`/auth`, 'SignIn_old');
return this.signIn(body);
}
@Post('login')
@HttpCode(HttpStatus.OK)
async signIn_login(@Body() body: AuthSignInRequest) {
console.log(`/auth`, 'SignIn_login');
return this.signIn(body);
}
@Post('sign-in')
@HttpCode(HttpStatus.OK)
async signIn(@Body() { username, password, totp }: AuthSignInRequest) {
console.log(`/auth`, 'SignIn');
const tokens = await this.authClient
.signIn({ username, password, totp })
.catch((err) => {
throw ErrorBuilder(err);
});
return tokens;
}
@Post('refresh-access-token')
@HttpCode(HttpStatus.OK)
async refreshAccessToken(
@Body() { refreshToken }: AuthRefreshAccessTokenRequest,
) {
console.log(`/auth`, 'RefreshAccessToken');
const accessToken = await this.authClient
.refreshAccessToken({ refreshToken })
.catch((err) => {
throw ErrorBuilder(err);
});
return accessToken;
}
@Post('enable-totp')
@HttpCode(HttpStatus.OK)
async enableTotpMFA(
@Body() body: AuthEnableTotpMfaRequest,
@Headers() headers,
) {
console.log(`/auth`, 'enable-totp');
const { password } = body;
const { authorization: accessToken } = headers;
const response = await this.authClient
.enableTotpMFA({ accessToken, password })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('disable-totp')
@HttpCode(HttpStatus.OK)
async disableTotpMFA(
@Body() body: AuthDisableTotpMfaRequest,
@Headers() headers,
) {
console.log(`/auth`, 'disable-totp');
const { password } = body;
const { authorization: accessToken } = headers;
const response = await this.authClient
.disableTotpMFA({ accessToken, password })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('dismiss-totp')
@HttpCode(HttpStatus.OK)
async dismissTotpMFA(@Headers() headers) {
console.log(`/auth`, 'disable-totp');
const { authorization: accessToken } = headers;
const response = await this.authClient
.dismissTotpMFA({ accessToken })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('verify-totp')
@HttpCode(HttpStatus.OK)
async verifyTotp(
@Body() body: AuthVerifyTotpMfaRequest,
@Headers() headers,
): Promise<any> {
console.log(`/auth`, 'enable-totp');
const { totp } = body;
const { authorization: accessToken } = headers;
const response = await this.authClient
.verifyTotp({ accessToken, totp })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('change-password')
@HttpCode(HttpStatus.OK)
async changePassword(
@Body() body: AuthChangePasswordRequest,
@Headers() headers,
): Promise<any> {
console.log(`/auth`, 'change-password');
const { oldPassword, newPassword } = body;
const { authorization: accessToken } = headers;
const response = await this.authClient
.changePassword({
accessToken,
oldPassword,
newPassword,
})
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('reset-password')
@HttpCode(HttpStatus.OK)
async resetPassword(@Body() body: AuthResetPasswordRequest): Promise<any> {
console.log(`/auth`, 'reset-password');
const { username } = body;
const response = await this.authClient
.resetPassword({ username })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('verify-reset-password-code')
@HttpCode(HttpStatus.OK)
async verifyResetPasswordCode(
@Body() body: AuthVerifyResetPasswordCodeRequest,
): Promise<any> {
console.log(`/auth`, 'verify-reset-password-code');
const { username, code } = body;
const response = await this.authClient
.verifyResetPasswordCode({ username, code })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('confirm-reset-password')
@HttpCode(HttpStatus.OK)
async confirmResetPassword(
@Body() body: AuthConfirmResetPasswordRequest,
): Promise<any> {
console.log(`/auth`, 'confirm-reset-password');
const { username, code, newPassword } = body;
const response = await this.authClient
.confirmResetPassword({ username, code, newPassword })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
}
+152
View File
@@ -0,0 +1,152 @@
import nock from 'nock';
import { LoggerMiddleware } from '../../middlewares/authentication';
import { NextFunction, Request, Response } from 'express';
import { ConsoleLogger, UnauthorizedException } from '@nestjs/common';
describe('PipelinesGrpcServerService', () => {
// let mockRequest: Partial<Request>;
// let mockResponse: Partial<Response>;
// const nextFunction: NextFunction = jest.fn();
// beforeEach(() => {
// mockRequest = {
// headers: {},
// body: {
// info: {},
// },
// };
// mockResponse = {
// json: jest.fn(),
// };
// });
it('should be defined', () => {
expect(2 + 2).toBe(4);
});
// it('Should be able to pass auth', async () => {
// const awsRegion = process.env.AWS_REGION;
// const awsPoolId = process.env.AWS_IDENTITY_POOL_ID;
// const cognitoRes = {
// keys: [
// {
// alg: 'RS256',
// e: 'AQAB',
// kid: 'z3VA3+i9JZY3JFDJTNWOap8RY+B7C6mFedaqCuvLvqA=',
// kty: 'RSA',
// n: 'vIGCQDkPA_eQUoaGDUsCyK_Whr76mNW0kZ1uac6ZnyY6hsjUIjvwehqv-ux3cQo4rQZQVFcoh8n9cK5jguz4GVdD972vIxoEdyv32nBFVr5e1PBunKJ2Y32GTR_Hl0XiE0hRe1v6cWuTqiC4qm1NY7tXYL3mI9L6s9ztNbhmG_V44y26PdhL4vRVrJaHOAmCs-77U-QYAC7Llkpmjh-8tG1zt9_FJ237cpBUVOuhD-7Nm32_eB9wddBGfBw0F10ko_KJoU-7683_Kv8k9coJzFUSONId-bfnLOzs8j1L6ZAHipXCR7rpmuRYzXztjp4Wmm2zPUToWLdMEy0Hq1OWmw',
// use: 'sig',
// },
// {
// alg: 'RS256',
// e: 'AQAB',
// kid: 'u+1W9pi+clp8LaPhZVrv4dXMqRkTRD02YWhbm0NvsUw=',
// kty: 'RSA',
// n: 'noGq1cRMAKJPWahqfC_zWasYovSUycaS1basMfEoh3ePLc9zRgmyfiVKYzLRosHMe1uk0Y5ekCBKnWA8Yl7I84Yt7IIIaE44oJjSEGBKT3m8i8YaXzawaNs63KPkRh8553o3KzL75bQWcI_ABKqkf-uAKSCl_XotBGkzLUl4hIOYtAtRGEfKaNMPqyTCT5Zn71pMd0isppaUiTW2T5QLsZV1IBp46aSrl_D5Q_FTsJT7feobQVoHp2zfIorCpkfTXBTBMQTEBFSDyPbc6cULl48VKxp0B0GEwR_kYCEHEVzf41LQcUWZUE0OdBychijkSc9MZJnBWUYQZyedJILWnQ',
// use: 'sig',
// },
// ],
// };
// nock(
// `https://cognito-idp.${awsRegion}.amazonaws.com/${awsPoolId}/.well-known/jwks.json`,
// )
// .persist()
// .get('')
// .reply(200, cognitoRes);
// mockRequest.headers['Dadosfera-User'] =
// 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiZTljYjI1ZGEtMTQyOC00NDJjLTg5NjItYTdkNmQxNjhkODUyIiwibmFtZSI6InJvZHJpZ28uemFtYm9uaSIsInVzZXJuYW1lIjoicm9kcmlnby56YW1ib25pQGRhZG9zZmVyYS5haSIsInJ1bGVJZCI6IjIxNzdmZjg4LThmY2ItNDRlNS1hYzYxLWNjYmU2Y2M3MGU4ZCIsImN1c3RvbWVySWQiOiIxMTI5ODBhMy0wYTEyLTQxYzktYmZmZC03OTFjZjdjYTg3YTIiLCJtZmFTdGF0dXMiOiJwZW5kaW5nIiwiY3JlYXRlZEF0IjoiMjAyMi0wNS0xM1QxNTowOTowOS4xMzhaIiwidXBkYXRlZEF0IjoiMjAyMi0wNS0xM1QxNTowOTowOS4xMzhaIiwicGVybWlzc2lvbnMiOlsiUE9TVCAvcGlwZWxpbmVzIiwiR0VUIC9waXBlbGluZXMiLCJQVVQgL3BpcGVsaW5lcyIsIkRFTEVURSAvcGlwZWxpbmVzIiwiUE9TVCAvaW5wdXRzIiwiR0VUIC9pbnB1dHMiLCJQVVQgL2lucHV0cyIsIkRFTEVURSAvaW5wdXRzIiwiUE9TVCAvb3V0cHV0cyIsIkdFVCAvb3V0cHV0cyIsIlBVVCAvb3V0cHV0cyIsIkRFTEVURSAvb3V0cHV0cyIsIlBPU1QgL3RyYW5zZm9ybWF0aW9ucyIsIkdFVCAvdHJhbnNmb3JtYXRpb25zIiwiUFVUIC90cmFuc2Zvcm1hdGlvbnMiLCJERUxFVEUgL3RyYW5zZm9ybWF0aW9ucyIsIlBPU1QgL2NhdGFsb2ciLCJHRVQgL2NhdGFsb2ciLCJQVVQgL2NhdGFsb2ciLCJERUxFVEUgL2NhdGFsb2ciLCJQT1NUIC9hdXRoIiwiR0VUIC9tZXRhYmFzZSIsIkdFVCAvc25vd2ZsYWtlIl0sImN1c3RvbWVyIjoiZGFkb3NmZXJhIn0sImlhdCI6MTY1MzY1NjE2NywiZXhwIjoxNjUzNzQyNTY3fQ.eeNEEUk_95KOxM-objS7gXz-SCVkNFYpEP688MfLkdI';
// mockRequest.headers['Authorization'] =
// 'eyJraWQiOiJ1KzFXOXBpK2NscDhMYVBoWlZydjRkWE1xUmtUUkQwMllXaGJtME52c1V3PSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIxYjkyZmFkMC1iNWVlLTQwMzAtOGRmYy1hZWM0MGQzYzdkYmUiLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMV9OVXY3WTJTeGoiLCJjbGllbnRfaWQiOiI0N3RrY3Jxc2NuajY3bWhnYmg3dXQ1YnJzNCIsIm9yaWdpbl9qdGkiOiJhZWJjNjA5NC1hYTJmLTRiZmUtOWExZi01ZWVhYTVmYzAwNDAiLCJldmVudF9pZCI6IjBhY2NjMzJiLTllNzktNGY2NS1iMDFiLWZhZGJlYzFhZWFiNiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE2NTM2NTYxNjcsImV4cCI6MTY1MzY1Nzk2NywiaWF0IjoxNjUzNjU2MTY3LCJqdGkiOiIyYTgzNDhmOC0xNDhlLTQ3NjctODcxYi00M2UyOGRjNjc2NTkiLCJ1c2VybmFtZSI6InJvZHJpZ28uemFtYm9uaUBkYWRvc2ZlcmEuYWkifQ.UgIgeGEH2olNgqPly8cymNgWIZJz5n9N4yeKgTusfGsu5h-TWP_jVhPoCvFoixO2XKzFjSCvKwlKQYZyB74jLQLs-j5C5KGBdOea1HX7pUnEfEVtBINd1kcHib5YpGYq3MHG1uVx8vNJS3XviwgYg4rgNWA4du-QbhMicdRyHolYM-dWxuxtkwTRWMe1Vw6KlTctFsvUWx1GMgjp37tsLONcp3B8OsYXfiR764K_pBNs5gMhJ39gJ7NHHLWkJrtrUTpIoHWaZS_HEgvVyQiJENQvK_bPDMPm_lyF1dW-JBgot4TpAxMmvV1XGabkzycIcAOwUaPsKBlMphgunz1Ffw';
// mockRequest.method = 'GET';
// mockRequest.route = {
// path: '/inputs/',
// stack: [
// {
// method: 'get',
// },
// ],
// methods: {
// get: true,
// },
// };
// const authMiddleware = new LoggerMiddleware();
// await authMiddleware.useTest(
// mockRequest as Request,
// mockResponse as Response,
// nextFunction,
// );
// expect(nextFunction).toHaveBeenCalled();
// });
// it('Should not be able to pass auth', async () => {
// const awsRegion = process.env.AWS_REGION;
// const awsPoolId = process.env.AWS_IDENTITY_POOL_ID;
// const cognitoRes = {
// keys: [
// {
// alg: 'RS256',
// e: 'AQAB',
// kid: 'z3VA3+i9JZY3JFDJTNWOap8RY+B7C6mFedaqCuvLvqA=',
// kty: 'RSA',
// n: 'vIGCQDkPA_eQUoaGDUsCyK_Whr76mNW0kZ1uac6ZnyY6hsjUIjvwehqv-ux3cQo4rQZQVFcoh8n9cK5jguz4GVdD972vIxoEdyv32nBFVr5e1PBunKJ2Y32GTR_Hl0XiE0hRe1v6cWuTqiC4qm1NY7tXYL3mI9L6s9ztNbhmG_V44y26PdhL4vRVrJaHOAmCs-77U-QYAC7Llkpmjh-8tG1zt9_FJ237cpBUVOuhD-7Nm32_eB9wddBGfBw0F10ko_KJoU-7683_Kv8k9coJzFUSONId-bfnLOzs8j1L6ZAHipXCR7rpmuRYzXztjp4Wmm2zPUToWLdMEy0Hq1OWmw',
// use: 'sig',
// },
// {
// alg: 'RS256',
// e: 'AQAB',
// kid: 'u+1W9pi+clp8LaPhZVrv4dXMqRkTRD02YWhbm0NvsUw=',
// kty: 'RSA',
// n: 'noGq1cRMAKJPWahqfC_zWasYovSUycaS1basMfEoh3ePLc9zRgmyfiVKYzLRosHMe1uk0Y5ekCBKnWA8Yl7I84Yt7IIIaE44oJjSEGBKT3m8i8YaXzawaNs63KPkRh8553o3KzL75bQWcI_ABKqkf-uAKSCl_XotBGkzLUl4hIOYtAtRGEfKaNMPqyTCT5Zn71pMd0isppaUiTW2T5QLsZV1IBp46aSrl_D5Q_FTsJT7feobQVoHp2zfIorCpkfTXBTBMQTEBFSDyPbc6cULl48VKxp0B0GEwR_kYCEHEVzf41LQcUWZUE0OdBychijkSc9MZJnBWUYQZyedJILWnQ',
// use: 'sig',
// },
// ],
// };
// nock(
// `https://cognito-idp.${awsRegion}.amazonaws.com/${awsPoolId}/.well-known/jwks.json`,
// )
// .persist()
// .get('')
// .reply(200, cognitoRes);
// mockRequest.headers['Dadosfera-User'] =
// 'asdeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiZTljYjI1ZGEtMTQyOC00NDJjLTg5NjItYTdkNmQxNjhkODUyIiwibmFtZSI6InJvZHJpZ28uemFtYm9uaSIsInVzZXJuYW1lIjoicm9kcmlnby56YW1ib25pQGRhZG9zZmVyYS5haSIsInJ1bGVJZCI6IjIxNzdmZjg4LThmY2ItNDRlNS1hYzYxLWNjYmU2Y2M3MGU4ZCIsImN1c3RvbWVySWQiOiIxMTI5ODBhMy0wYTEyLTQxYzktYmZmZC03OTFjZjdjYTg3YTIiLCJtZmFTdGF0dXMiOiJwZW5kaW5nIiwiY3JlYXRlZEF0IjoiMjAyMi0wNS0xM1QxNTowOTowOS4xMzhaIiwidXBkYXRlZEF0IjoiMjAyMi0wNS0xM1QxNTowOTowOS4xMzhaIiwicGVybWlzc2lvbnMiOlsiUE9TVCAvcGlwZWxpbmVzIiwiR0VUIC9waXBlbGluZXMiLCJQVVQgL3BpcGVsaW5lcyIsIkRFTEVURSAvcGlwZWxpbmVzIiwiUE9TVCAvaW5wdXRzIiwiR0VUIC9pbnB1dHMiLCJQVVQgL2lucHV0cyIsIkRFTEVURSAvaW5wdXRzIiwiUE9TVCAvb3V0cHV0cyIsIkdFVCAvb3V0cHV0cyIsIlBVVCAvb3V0cHV0cyIsIkRFTEVURSAvb3V0cHV0cyIsIlBPU1QgL3RyYW5zZm9ybWF0aW9ucyIsIkdFVCAvdHJhbnNmb3JtYXRpb25zIiwiUFVUIC90cmFuc2Zvcm1hdGlvbnMiLCJERUxFVEUgL3RyYW5zZm9ybWF0aW9ucyIsIlBPU1QgL2NhdGFsb2ciLCJHRVQgL2NhdGFsb2ciLCJQVVQgL2NhdGFsb2ciLCJERUxFVEUgL2NhdGFsb2ciLCJQT1NUIC9hdXRoIiwiR0VUIC9tZXRhYmFzZSIsIkdFVCAvc25vd2ZsYWtlIl0sImN1c3RvbWVyIjoiZGFkb3NmZXJhIn0sImlhdCI6MTY1MzY1NjE2NywiZXhwIjoxNjUzNzQyNTY3fQ.eeNEEUk_95KOxM-objS7gXz-SCVkNFYpEP688MfLkdI';
// mockRequest.headers['Authorization'] =
// 'asdeyJraWQiOiJ1KzFXOXBpK2NscDhMYVBoWlZydjRkWE1xUmtUUkQwMllXaGJtME52c1V3PSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIxYjkyZmFkMC1iNWVlLTQwMzAtOGRmYy1hZWM0MGQzYzdkYmUiLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMV9OVXY3WTJTeGoiLCJjbGllbnRfaWQiOiI0N3RrY3Jxc2NuajY3bWhnYmg3dXQ1YnJzNCIsIm9yaWdpbl9qdGkiOiJhZWJjNjA5NC1hYTJmLTRiZmUtOWExZi01ZWVhYTVmYzAwNDAiLCJldmVudF9pZCI6IjBhY2NjMzJiLTllNzktNGY2NS1iMDFiLWZhZGJlYzFhZWFiNiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE2NTM2NTYxNjcsImV4cCI6MTY1MzY1Nzk2NywiaWF0IjoxNjUzNjU2MTY3LCJqdGkiOiIyYTgzNDhmOC0xNDhlLTQ3NjctODcxYi00M2UyOGRjNjc2NTkiLCJ1c2VybmFtZSI6InJvZHJpZ28uemFtYm9uaUBkYWRvc2ZlcmEuYWkifQ.UgIgeGEH2olNgqPly8cymNgWIZJz5n9N4yeKgTusfGsu5h-TWP_jVhPoCvFoixO2XKzFjSCvKwlKQYZyB74jLQLs-j5C5KGBdOea1HX7pUnEfEVtBINd1kcHib5YpGYq3MHG1uVx8vNJS3XviwgYg4rgNWA4du-QbhMicdRyHolYM-dWxuxtkwTRWMe1Vw6KlTctFsvUWx1GMgjp37tsLONcp3B8OsYXfiR764K_pBNs5gMhJ39gJ7NHHLWkJrtrUTpIoHWaZS_HEgvVyQiJENQvK_bPDMPm_lyF1dW-JBgot4TpAxMmvV1XGabkzycIcAOwUaPsKBlMphgunz1Ffw';
// mockRequest.method = 'GET';
// mockRequest.route = {
// path: '/inputs/',
// stack: [
// {
// method: 'get',
// },
// ],
// methods: {
// get: true,
// },
// };
// const authMiddleware = new LoggerMiddleware();
// // const t = await authMiddleware.useTest(
// // mockRequest as Request,
// // mockResponse as Response,
// // nextFunction,
// // );
// // expect(nextFunction).toHaveBeenCalled();
// expect(async () => {
// const t = await authMiddleware.useTest(
// mockRequest as Request,
// mockResponse as Response,
// nextFunction,
// );
// console.log(t);
// }).toThrow('Unauthorized');
// expect(1).toBe(2);
// // expect(t).toThrow(UnauthorizedException);
// });
});
+302
View File
@@ -0,0 +1,302 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Query,
} from '@nestjs/common';
import { CatalogService } from './catalog.service';
@Controller('catalog')
export class CatalogController {
constructor(private catalogService: CatalogService) {}
@Get('all')
async catalogAll(@Body() body) {
console.log(`/catalog`, 'ON CATALOG ALL ROUTE');
const res = await this.catalogService.catalogAll(body);
return res;
}
@Get('data_apps')
async dataAppsAll(@Body() body) {
console.log(`/catalog`, 'ON FIND ALL DATA APPS ROUTE');
const res = await this.catalogService.dataAppsAll(body);
return res;
}
@Delete('data_apps/:id')
async dataAppsOne(@Param() params, @Body() body) {
console.log(`/catalog`, 'ON FIND ONE DATA APP ROUTE');
const { id } = params;
const res = await this.catalogService.dataAppsOne(id, body);
return res;
}
@Get('dashboard-metabase')
async getAllDashboardMetabase(@Body() body) {
console.log(`/catalog`, 'ON GET ALL DASHBOARDS METABASE ROUTE');
const res = await this.catalogService.getAllDashboardMetabase(body);
return res;
}
@Get('dashboard-metabase/:id')
async getOneDashboardMetabase(@Body() body, @Param() params) {
const { id } = params;
console.log(`/catalog`, 'ON GET ONE DASHBOARD METABASE ROUTE');
const res = await this.catalogService.getOneDashboardMetabase(id, body);
return res;
}
@Get('table-metadata')
async getAllTableMetadata(@Body() body, @Query() query) {
console.log(`/catalog`, 'ON GET ALL TABLES METADATA ROUTE');
if (!query) {
const res = await this.catalogService.getAllTableMetadata(body);
return res;
} else {
const res = await this.catalogService.getOneTableMetadata(body, query);
return res;
}
}
@Delete('table-metadata/:id')
async deleteOneTableMetadata(@Param() params, @Body() body) {
const { id } = params;
console.log(`/catalog`, 'ON DELETE ONE TABLE METADATA ROUTE');
const res = await this.catalogService.deleteOneTableMetadata(id, body);
return res;
}
@Get('column-metadata')
async getOneColumnMetadata(@Body() body, @Query() params) {
console.log(`/catalog`, 'ON GET ONE COLUMN METADATA ROUTE');
const res = await this.catalogService.getOneColumnMetadata(body, params);
return res;
}
@Delete('column-metadata/:id')
async deleteOneColumnMetadata(@Param() params, @Body() body) {
console.log(`/catalog`, 'ON DELETE ONE COLUMN METADATA ROUTE');
const { id } = params;
const res = await this.catalogService.deleteOneColumnMetadata(id, body);
return res;
}
@Get('data-preview')
async getOneDataPreview(@Body() body, @Query() params) {
console.log(`/catalog`, 'ON GET ONE DATAPREVIEW ROUTE');
const res = await this.catalogService.getOneDataPreview(body, params);
return res;
}
@Get('data-status')
async getDataStatus(@Body() body) {
console.log(`/catalog`, 'ON GET DATA STATUS ROUTE');
const res = await this.catalogService.getDataStatus(body);
return res;
}
@Get('data-status')
async createDataStatus(@Body() body) {
console.log(`/catalog`, 'ON CREATE DATA STATUS ROUTE');
const res = await this.catalogService.createDataStatus(body);
return res;
}
@Get('data-description')
async getDataDescription(@Body() body) {
console.log(`/catalog`, 'ON GET DATA DESCRIPTION ROUTE');
const res = await this.catalogService.getDataDescription(body);
return res;
}
@Post('data-description')
async createDataDescription(@Body() body) {
console.log(`/catalog`, 'ON CREATE DATA DESCRIPTION ROUTE');
const res = await this.catalogService.createDataDescription(body);
return res;
}
@Get('data-docs')
async getDataDocs(@Body() body) {
console.log(`/catalog`, 'ON GET DATA DOCS ROUTE');
const res = await this.catalogService.getDataDocs(body);
return res;
}
@Post('data-docs')
async createDataDocs(@Body() body) {
console.log(`/catalog`, 'ON CREATE DATA DOCS ROUTE');
const res = await this.catalogService.createDataDocs(body);
return res;
}
@Get('data-rating')
async getDataRating(@Body() body) {
console.log(`/catalog`, 'ON GET DATA RATING ROUTE');
const res = await this.catalogService.getDataRating(body);
return res;
}
@Post('data-rating')
async createDataRating(@Body() body) {
console.log(`/catalog`, 'ON GET DATA RATING ROUTE');
const res = await this.catalogService.createDataRating(body);
return res;
}
@Get('summary-rating/:id')
async getSummaryRating() {
console.log(`/catalog`, 'ON GET SUMMARY RATING ROUTE');
//const { id } = params;
//
//const res = await this.catalogService.getSummaryRating(id, body);
return {
avg_rating: 0,
rating_count: 0,
};
}
@Get('data-comment')
async getDataComment(@Body() body) {
console.log(`/catalog`, 'ON GET DATA COMMENT ROUTE');
const res = await this.catalogService.getDataComment(body);
return res;
}
@Post('data-comment')
async createDataComment(@Body() body) {
console.log(`/catalog`, 'ON GET DATA COMMENT ROUTE');
const res = await this.catalogService.createDataComment(body);
return res;
}
@Get('data-review')
async getDataReview(@Body() body, @Query() params) {
console.log(`/catalog`, 'ON GET DATA REVIEW ROUTE');
const res = await this.catalogService.getDataReview(body, params);
return res;
}
@Post('tags')
async createTags(@Body() body) {
console.log(`/catalog`, 'ON CREATE TAG ROUTE');
const res = await this.catalogService.createTags(body);
return res;
}
@Get('tags')
async findAllTags(@Body() body) {
console.log(`/catalog`, 'ON FIND ALL TAGS ROUTE');
const res = await this.catalogService.findAllTags(body);
return res;
}
@Delete('tags/:id')
async deleteTags(@Param() params, @Body() body) {
console.log(`/catalog`, 'ON DELETE TAG ROUTE');
const { id } = params;
const res = await this.catalogService.deleteTags(id, body);
return res;
}
@Post('table-tags')
async createTableTags(@Body() body) {
console.log(`/catalog`, 'ON CREATE TABLE TAG ROUTE');
const res = await this.catalogService.createTableTags(body);
return res;
}
@Get('table-tags')
async getAllTableTags(@Body() body) {
console.log(`/catalog`, 'ON GET ALL TABLE TAGS ROUTE');
const res = await this.catalogService.findAllTableTags(body);
return res;
}
@Delete('table-tags/:id')
async deleteTableTags(@Param() params, @Body() body) {
console.log(`/catalog`, 'ON CREATE TABLE TAGS ROUTE');
const { id } = params;
const res = await this.catalogService.deleteTableTags(id, body);
return res;
}
@Get('table-rules')
async getTableRules(@Body() body) {
console.log(`/catalog`, 'ON GET TABLE RULES ROUTE');
const res = await this.catalogService.getTableRules(body);
return res;
}
@Delete('table-rules/:id')
async deleteTableRules(@Param() params, @Body() body) {
console.log(`/catalog`, 'ON DELETE TABLE RULES ROUTE');
const { id } = params;
const res = await this.catalogService.deleteTableRules(id, body);
return res;
}
}
+263
View File
@@ -0,0 +1,263 @@
import axios from 'axios';
class CatalogService {
_getNimbusUrl(body) {
const customer = body.info.customer.toLowerCase();
if (process.env.ENV === 'prd') {
return `https://nimbus-${customer}.dadosfera.ai`;
}
return `https://nimbus-${customer}.${process.env.ENV}.dadosfera.ai`;
}
async catalogAll(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/all/`);
return data;
}
async dataAppsAll(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/data_apps/`);
return data;
}
async dataAppsOne(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/data_apps/${id}/`,
);
return data;
}
async getAllDashboardMetabase(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/dashboard-metabase/`,
);
return data;
}
async getOneDashboardMetabase(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/dashboard-metabase/${id}`,
);
console.log(data);
// const [, path] = data.iframe_url.split('.dadosfera');
// const host = `httpss://metabase-${body.info.customer.toLowerCase()}.dadosfera.ai`;
// data.iframe_url = host + path;
return data;
}
async getAllTableMetadata(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/table-metadata/`,
);
return data;
}
async getOneTableMetadata(body, params) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/table-metadata/`,
{ params: params },
);
return data;
}
async deleteOneTableMetadata(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.delete(
`${nimbusUrl}/api/catalog/table-metadata/${id}`,
);
return data;
}
async getOneColumnMetadata(body, params) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/column-metadata/`,
{ params: params },
);
return data;
}
async deleteOneColumnMetadata(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.delete(
`${nimbusUrl}/api/catalog/column-metadata/${id}/`,
);
return data;
}
async getOneDataPreview(body, params) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/data-preview/`, {
params: params,
});
return data;
}
async getDataStatus(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/data-status/`);
return data;
}
async createDataStatus(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(
`${nimbusUrl}/api/catalog/data-status/`,
body,
);
return data;
}
async getDataDescription(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/data-description/`,
);
return data;
}
async createDataDescription(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(
`${nimbusUrl}/api/catalog/data-description/`,
body,
);
return data;
}
async getDataDocs(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/data-docs/`);
return data;
}
async createDataDocs(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(
`${nimbusUrl}/api/catalog/data-docs/`,
body,
);
return data;
}
async getDataRating(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/data-rating/`);
return data;
}
async createDataRating(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(
`${nimbusUrl}/api/catalog/data-rating/`,
body,
);
return data;
}
async getSummaryRating(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/summary-rating/${id}`,
);
return data;
}
async getDataComment(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/data-comment/`);
return data;
}
async createDataComment(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(
`${nimbusUrl}/api/catalog/data-comment/`,
body,
);
return data;
}
async getDataReview(body, params) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/data-review/`, {
params: params,
});
return data;
}
async createTags(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(`${nimbusUrl}/api/catalog/tags/`, body);
return data;
}
async findAllTags(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(`${nimbusUrl}/api/catalog/tags/`, body);
return data;
}
async findAllTableTags(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/table-tags/`,
body,
);
return data;
}
async deleteTags(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.delete(`${nimbusUrl}/api/catalog/tags/${id}`);
return data;
}
async createTableTags(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.post(
`${nimbusUrl}/api/catalog/table-tags/`,
body,
);
return data;
}
async deleteTableTags(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.delete(
`${nimbusUrl}/api/catalog/table-tags/${id}`,
);
return data;
}
async getTableRules(body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.get(
`${nimbusUrl}/api/catalog/table-rules/`,
body,
);
return data;
}
async deleteTableRules(id, body) {
const nimbusUrl = this._getNimbusUrl(body);
const { data } = await axios.delete(
`${nimbusUrl}/api/catalog/table-rules/${id}`,
);
return data;
}
}
export { CatalogService };
@@ -7,6 +7,7 @@ export class HealthController {
@Get()
check() {
console.log(`/health`, 'check');
return this.healthService.check();
}
}
@@ -0,0 +1,5 @@
describe('PipelinesGrpcServerService', () => {
it('should be defined', () => {
expect(2 + 2).toBe(4);
});
});
@@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common';
@Injectable()
export class HealthService {
check() {
console.log('HEALTH');
return { message: 'Ok' };
}
}
+100
View File
@@ -0,0 +1,100 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Patch,
Post,
} from '@nestjs/common';
import { InputsService } from './inputs.service';
import { InputsClientService } from 'src/clients/inputs/client.service';
import { UpdateInputRequest } from 'src/clients/inputs/interfaces';
import { InputNewCreateRequest } from '@victorradael/protospack';
@Controller('inputs')
export class InputsController {
constructor(private inputsClientService: InputsClientService) {}
@Post('/test-connection')
async testConnection(@Body() data) {
console.log(`/test-connection`, 'ON TEST CONNECTION ROUTE');
const inputService = new InputsService(this.inputsClientService);
const response = await inputService.testConnection(data);
return response;
}
@Post('/test-connection/get-columns')
async getColumns(@Body() data) {
console.log(
`/test-connection/get-columns`,
'ON TEST CONNECTION GET COLUMNS ROUTE',
);
const inputService = new InputsService(this.inputsClientService);
const response = await inputService.getColumns(data);
return response;
}
@Post()
async create(@Body() createInputDto: InputNewCreateRequest) {
console.log(`/input`, 'ON CREATE ROUTE');
const inputService = new InputsService(this.inputsClientService);
const response = await inputService.create(createInputDto);
return response;
}
@Get()
async findAll(@Body() body) {
console.log(`/input`, 'ON FIND ALL ROUTE');
const inputService = new InputsService(this.inputsClientService);
const response = await inputService.findAll(body);
return response;
}
@Get('/:id')
async findOne(@Body() body, @Param() params) {
const { id } = params;
console.log(`/input/${id}`, 'ON FIND ONE ROUTE');
const inputService = new InputsService(this.inputsClientService);
const response = await inputService.findOne({ id, ...body });
return response;
}
@Patch(':id')
async update(@Body() updateInputDto: UpdateInputRequest, @Param() params) {
const { id } = params;
const { info } = updateInputDto;
delete updateInputDto.info;
console.log(`/input/${id}`, 'ON UPDATE ROUTE');
const inputService = new InputsService(this.inputsClientService);
const response = await inputService.update(id, updateInputDto, info);
return response;
}
@Delete(':id')
async delete(@Body() data, @Param() params) {
const { id } = params;
console.log(`/input/${id}`, 'ON DELETE ROUTE');
const inputService = new InputsService(this.inputsClientService);
const response = await inputService.remove({ id, ...data });
return response;
}
}
@@ -0,0 +1,5 @@
describe('PipelinesGrpcServerService', () => {
it('should be defined', () => {
expect(2 + 2).toBe(4);
});
});
+142
View File
@@ -0,0 +1,142 @@
import { Body, HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Timeout } from '@nestjs/schedule';
import { InputsClientService } from 'src/clients/inputs/client.service';
import { IIdRequest, Info } from 'src/clients/inputs/interfaces';
@Injectable()
export class InputsService {
constructor(private inputClient: InputsClientService) {}
adjustInputPayload(payload) {
return payload?.input_s3 || payload?.input_jdbc;
}
async create(@Body() data) {
try {
if (
data.plugin == 'csv' ||
data.plugin == 'json' ||
data.plugin == 'parquet'
) {
const { info, ...input } = data;
const inputPayload = this.generateInputS3Payload(input);
const createInputResponse = await this.inputClient.createS3Inputs({
input: inputPayload,
info,
});
return createInputResponse;
} else {
const createInputResponse: any = await this.inputClient.create(data);
if (createInputResponse?.input?.input_jdbc) {
return { input: createInputResponse?.input?.input_jdbc };
}
return createInputResponse;
}
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async findAll(body) {
try {
const findAllInputResponse: any = await this.inputClient.findAll(body);
if (findAllInputResponse?.inputs?.length) {
findAllInputResponse.inputs = findAllInputResponse.inputs.map((input) =>
this.adjustInputPayload(input),
);
}
return findAllInputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async findOne(idRequest: IIdRequest) {
try {
const findOneInputResponse: any = await this.inputClient.findOne(
idRequest,
);
findOneInputResponse.input = this.adjustInputPayload(
findOneInputResponse.input,
);
return findOneInputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async update(id: string, data, info: Info) {
try {
const updateInputResponse: any = await this.inputClient.update({
id,
info,
...data,
});
updateInputResponse.input = this.adjustInputPayload(
updateInputResponse?.input,
);
return updateInputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async remove(idRequest: IIdRequest) {
try {
const removeInputResponse = await this.inputClient.remove(idRequest);
return removeInputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
@Timeout(60000 * 10) // Timeout set for 10 minutes
async testConnection(data) {
try {
const testConnectionInputResponse = await this.inputClient.testConnection(
data,
);
return testConnectionInputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async getColumns(data) {
try {
const testConnectionGetColumnsResponse =
await this.inputClient.getColumns(data);
return testConnectionGetColumnsResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
generateInputS3Payload(payload) {
const { credentials, plugin } = payload;
if (!credentials) return payload;
const {
client_aws_access_key_id,
client_aws_secret_access_key,
file_format_params,
format_file_params,
client_bucket,
file_to_extract,
} = credentials;
const formatedPayload = {
plugin,
source_bucket: client_bucket,
source_prefix: file_to_extract,
auth_parameters: {
aws_access_key_id: client_aws_access_key_id,
aws_secret_access_key: client_aws_secret_access_key,
},
file_format_params: file_format_params || format_file_params,
};
return formatedPayload;
}
}
@@ -0,0 +1,73 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { Payload } from '@nestjs/microservices';
import { OutputsClientService } from 'src/clients/outputs/client.service';
import { OutputsService } from './outputs.service';
@Controller('outputs')
export class OutputsController {
constructor(private outputsClientService: OutputsClientService) {}
@Post()
async create(@Body() createOutputDto) {
console.log(process.env.DEV_URL + `/output`, 'ON CREATE ROUTE');
const outputService = new OutputsService(this.outputsClientService);
const response = await outputService.create(createOutputDto);
return response;
}
@Get()
async findAll(@Body() data) {
console.log(process.env.DEV_URL + `/output`, 'ON Find All ROUTE');
const outputService = new OutputsService(this.outputsClientService);
const response = await outputService.findAll(data);
return response;
}
@Get('/:id')
async findOne(@Body() data, @Param() params) {
const { id } = params;
console.log(process.env.DEV_URL + `/output/${id}`, 'ON Find One ROUTE');
const outputService = new OutputsService(this.outputsClientService);
const response = await outputService.findOne({ id, ...data });
return response;
}
@Put(':id')
async update(@Payload() updateOutputDto, @Param() params) {
const { id } = params;
const { info } = updateOutputDto;
delete updateOutputDto.info;
console.log(process.env.DEV_URL + `/output/${id}`, 'ON UPDATE ROUTE');
const outputService = new OutputsService(this.outputsClientService);
const response = await outputService.update(id, updateOutputDto, info);
return response;
}
@Delete(':id')
async delete(@Body() data, @Param() params) {
const { id } = params;
console.log(process.env.DEV_URL + `/output/${id}`, 'ON DELETE ROUTE');
const outputService = new OutputsService(this.outputsClientService);
const response = await outputService.remove({ id, ...data });
return response;
}
}
@@ -0,0 +1,5 @@
describe('PipelinesGrpcServerService', () => {
it('should be defined', () => {
expect(2 + 2).toBe(4);
});
});
+63
View File
@@ -0,0 +1,63 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { IIdRequest, Info } from 'src/clients/outputs/interfaces';
import { OutputsClientService } from 'src/clients/outputs/client.service';
@Injectable()
export class OutputsService {
constructor(private outputClient: OutputsClientService) {}
async create(createOutputDto) {
try {
const createOutputResponse = await this.outputClient.create(
createOutputDto,
);
return createOutputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async findOne(data: IIdRequest) {
try {
const findOneOutputResponse = await this.outputClient.findOne(data);
return findOneOutputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async findAll(data) {
try {
const findAllOutputResponse = await this.outputClient.findAll(data);
return findAllOutputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async update(id: string, data, info: Info) {
try {
const updateOutputResponse = await this.outputClient.update({
id,
info,
...data,
});
return updateOutputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async remove(data: IIdRequest) {
try {
const removeOutputResponse = await this.outputClient.remove(data);
return removeOutputResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
}
@@ -0,0 +1,118 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { PipelinesClientService } from 'src/clients/pipelines/client.service';
import { PipelinesService } from './pipelines.service';
@Controller('pipelines')
export class PipelinesController {
constructor(private pipelinesClientService: PipelinesClientService) {}
@Post('start/:id')
async activate(@Param() params, @Body() body) {
const { id } = params;
const { info } = body;
console.log(
process.env.DEV_URL + `/pipeline/start/${id}`,
'ON START PIPELINE ROUTE',
);
const pipelineService = new PipelinesService(this.pipelinesClientService);
const response = await pipelineService.runPipeline({ id, info });
return response;
}
@Get(':id/status')
async getPipelineStatus(@Body() body, @Param() params) {
const { id } = params;
body.id = id;
console.log(
process.env.DEV_URL + `/pipeline/${id}`,
'ON GET PIPELINE STATUS ROUTE',
);
const pipelineService = new PipelinesService(this.pipelinesClientService);
const response = await pipelineService.getPipelineStatus(body);
return response;
}
@Get(':id/:details')
async getPipelineLogs(@Param() params) {
const { id, details } = params;
console.log(
process.env.DEV_URL + `/pipeline/${id}`,
'ON GET PIPELINE LOGS ROUTE',
);
const pipelineService = new PipelinesService(this.pipelinesClientService);
const response = await pipelineService.getPipelineLogsMessages(id, details);
return response;
}
@Post()
async create(@Body() createPipelineDto) {
console.log(process.env.DEV_URL + `/pipelines`, 'ON CREATE ROUTE');
const pipelineService = new PipelinesService(this.pipelinesClientService);
const response = await pipelineService.create(createPipelineDto);
return response;
}
@Get()
async findAll(@Body() data) {
console.log(process.env.DEV_URL + `/pipeline`, 'ON Find All ROUTE');
const pipelineService = new PipelinesService(this.pipelinesClientService);
const response = await pipelineService.findAll(data);
return response;
}
@Get('/:id')
async findOne(@Body() data, @Param() params) {
const { id } = params;
console.log(process.env.DEV_URL + `/pipeline/${id}`, 'ON Find One ROUTE');
const pipelineService = new PipelinesService(this.pipelinesClientService);
const response = await pipelineService.findOne({ id, ...data });
return response;
}
@Put(':id')
async update(@Body() updatePipelineDto, @Param() params) {
const { id } = params;
const { info } = updatePipelineDto;
delete updatePipelineDto.info;
console.log(process.env.DEV_URL + `/pipeline/${id}`, 'ON UPDATE ROUTE');
const pipelineService = new PipelinesService(this.pipelinesClientService);
const response = await pipelineService.update(id, updatePipelineDto, info);
return response;
}
@Delete(':id')
async delete(@Body() data, @Param() params) {
const { id } = params;
console.log(process.env.DEV_URL + `/pipeline/${id}`, 'ON DELETE ROUTE');
const pipelineService = new PipelinesService(this.pipelinesClientService);
const response = await pipelineService.remove({ id, ...data });
return response;
}
}
@@ -0,0 +1,5 @@
describe('PipelinesGrpcServerService', () => {
it('should be defined', () => {
expect(2 + 2).toBe(4);
});
});
+118
View File
@@ -0,0 +1,118 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { PipelinesClientService } from 'src/clients/pipelines/client.service';
import { IIdRequest, Info } from 'src/clients/pipelines/interfaces';
import { objectCamelToSnake } from 'src/utils/CaseConverter';
@Injectable()
export class PipelinesService {
constructor(private pipelineClient: PipelinesClientService) {}
adjustPayload(payload) {
payload.input = payload.input?.input_s3 || payload.input?.input_jdbc;
}
async create(createPipelineDto) {
try {
const createPipelineResponse = await this.pipelineClient.create(
createPipelineDto,
);
const pipeline = objectCamelToSnake(createPipelineResponse);
this.adjustPayload(pipeline.pipeline);
return pipeline;
} catch (err) {
console.log(err);
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async findOne(data: IIdRequest) {
try {
const findOnePipelineResponse = await this.pipelineClient.findOne(data);
const pipeline = objectCamelToSnake(findOnePipelineResponse);
this.adjustPayload(pipeline.pipeline);
return pipeline;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async findAll(data) {
try {
const findAllPipelineResponse = await this.pipelineClient.findAll(data);
const pipelines = objectCamelToSnake(findAllPipelineResponse);
pipelines.forEach((pipeline) => {
this.adjustPayload(pipeline);
});
return { pipelines };
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async update(id: string, data, info: Info) {
try {
const updatePipelineResponse = await this.pipelineClient.update({
id,
info,
...data,
});
const pipeline = objectCamelToSnake(updatePipelineResponse);
this.adjustPayload(pipeline);
return pipeline;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async remove(data: IIdRequest) {
try {
const removePipelineResponse = await this.pipelineClient.remove(data);
return removePipelineResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async getPipelineLogsMessages(id: string, details: string) {
try {
const pipelineLogsResponse =
await this.pipelineClient.getPipelineLogsMessages({ id, details });
return objectCamelToSnake(pipelineLogsResponse);
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async getPipelineStatus(data: IIdRequest) {
try {
const pipelineStatusResponse =
await this.pipelineClient.getPipelineStatus(data);
return objectCamelToSnake(pipelineStatusResponse);
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async runPipeline({ id, info }: IIdRequest) {
try {
const triggerPipelineResponse = await this.pipelineClient.runPipeline({
id,
info,
});
return objectCamelToSnake(triggerPipelineResponse);
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
}
@@ -0,0 +1,97 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { Payload } from '@nestjs/microservices';
import { TransformationsClientService } from 'src/clients/transformations/client.service';
import { IIdRequest } from 'src/clients/transformations/interfaces';
import { TransformationsService } from './transformations.service';
@Controller('transformations')
export class TransformationsController {
constructor(
private transformationsClientService: TransformationsClientService,
) {}
@Post()
async create(@Body() createTransformationDto) {
console.log(process.env.DEV_URL + `/transformation`, 'ON CREATE ROUTE');
const transformationService = new TransformationsService(
this.transformationsClientService,
);
const response = await transformationService.create(
createTransformationDto,
);
return response;
}
@Get()
async findAll(@Body() data: IIdRequest) {
console.log(process.env.DEV_URL + `/transformation`, 'ON Find All ROUTE');
const transformationService = new TransformationsService(
this.transformationsClientService,
);
const response = await transformationService.findAll(data);
return response;
}
@Get('/:id')
async findOne(@Body() data, @Param() params) {
const { id } = params;
console.log(
process.env.DEV_URL + `/transformation/${id}`,
'ON Find One ROUTE',
);
const transformationService = new TransformationsService(
this.transformationsClientService,
);
const response = await transformationService.findOne({ id, ...data });
return response;
}
@Put(':id')
async update(@Payload() updateTransformationDto, @Param() params) {
const { id } = params;
console.log(
process.env.DEV_URL + `/transformation/${id}`,
'ON UPDATE ROUTE',
);
const transformationService = new TransformationsService(
this.transformationsClientService,
);
const response = await transformationService.update(
id,
updateTransformationDto,
);
return response;
}
@Delete(':id')
async delete(@Body() data, @Param() params) {
const { id } = params;
console.log(
process.env.DEV_URL + `/transformation/${id}`,
'ON DELETE ROUTE',
);
const transformationService = new TransformationsService(
this.transformationsClientService,
);
const response = await transformationService.remove({ id, ...data });
return response;
}
}
@@ -0,0 +1,5 @@
describe('PipelinesGrpcServerService', () => {
it('should be defined', () => {
expect(2 + 2).toBe(4);
});
});
@@ -0,0 +1,79 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { TransformationsClientService } from 'src/clients/transformations/client.service';
import {
ICreateTransformationsRequest,
IIdRequest,
} from 'src/clients/transformations/interfaces';
import { trSnakeToCamel } from 'src/utils/CaseConverter';
@Injectable()
export class TransformationsService {
constructor(private transformationClient: TransformationsClientService) {}
async create(createTransformationDto: ICreateTransformationsRequest) {
const { transformations, info } = createTransformationDto;
if (!transformations || transformations.length == 0) {
throw new HttpException('Missing transformations field.', 400);
}
try {
const convertedDTO = transformations.map((tr) => {
return trSnakeToCamel(tr);
});
const createTransformationResponse =
await this.transformationClient.create({
transformations: convertedDTO,
info: info,
});
return createTransformationResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async findOne(data: IIdRequest) {
try {
const findOneTransformationResponse =
await this.transformationClient.findOne(data);
return findOneTransformationResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async findAll(data) {
try {
const findAllTransformationResponse =
await this.transformationClient.findAll(data);
return findAllTransformationResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async update(id: string, data) {
try {
data.transformation['id'] = id;
const updateTransformationResponse =
await this.transformationClient.update({ ...data });
return updateTransformationResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
async remove(data: IIdRequest) {
try {
const removeTransformationResponse =
await this.transformationClient.remove(data);
return removeTransformationResponse;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
}
}
-17
View File
@@ -1,17 +0,0 @@
import { join } from 'path';
import { ClientOptions, Transport } from '@nestjs/microservices';
export const GrpcClientConfiguration: ClientOptions = {
transport: Transport.GRPC,
options: {
//url: `${process.env.USERS_SVC_URL}:${process.env.USERS_SVC_PORT}`,
url: `127.0.0.1:50053`,
package: 'output',
protoPath: join(__dirname, '..', 'proto', 'output.proto'),
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
-7
View File
@@ -1,7 +0,0 @@
export class CreateOutputDto {
name:string;
plugin:string;
values:string;
operation:string;
}
-6
View File
@@ -1,6 +0,0 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreateOutputDto } from './create-output.dto';
export class UpdateOutputDto extends PartialType(CreateOutputDto) {
}
-9
View File
@@ -1,9 +0,0 @@
export class Output {
id:string;
name:string;
plugin:string;
values:string;
operation:string;
}
-20
View File
@@ -1,20 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { OutputsController } from './outputs.controller';
import { OutputsService } from './outputs.service';
describe('OutputsController', () => {
let controller: OutputsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [OutputsController],
providers: [OutputsService],
}).compile();
controller = module.get<OutputsController>(OutputsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
-57
View File
@@ -1,57 +0,0 @@
import {
Controller,
Delete,
Get,
OnModuleInit,
Param,
Post,
Put,
} from '@nestjs/common';
import {
Client,
ClientGrpc,
MessagePattern,
Payload,
} from '@nestjs/microservices';
import { OutputsService } from './outputs.service';
import { CreateOutputDto } from './dto/create-output.dto';
import { UpdateOutputDto } from './dto/update-output.dto';
import { ApiTags } from '@nestjs/swagger';
import { GrpcClientConfiguration } from './config/grpc-client';
@Controller('output')
export class OutputsController implements OnModuleInit {
@Client(GrpcClientConfiguration)
private outputServiceClient: ClientGrpc;
private outputService: OutputsService;
onModuleInit() {
this.outputService =
this.outputServiceClient.getService<OutputsService>('OutputService');
}
@Post()
create(@Payload() createOutputDto: CreateOutputDto) {
return this.outputService.create(createOutputDto);
}
@Get()
list() {
return this.outputService.list();
}
@Get(':id')
show(@Param() id: string) {
return this.outputService.show(id);
}
@Put(':id')
update(@Param() id: string, @Payload() updateOutputDto: UpdateOutputDto) {
return this.outputService.update(id, updateOutputDto);
}
@Delete(':id')
remove(@Param() id: string) {
return this.outputService.remove(id);
}
}
-9
View File
@@ -1,9 +0,0 @@
import { Module } from '@nestjs/common';
import { OutputsService } from './outputs.service';
import { OutputsController } from './outputs.controller';
@Module({
controllers: [OutputsController],
providers: [OutputsService],
})
export class OutputsModule {}
-18
View File
@@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { OutputsService } from './outputs.service';
describe('OutputsService', () => {
let service: OutputsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [OutputsService],
}).compile();
service = module.get<OutputsService>(OutputsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
-26
View File
@@ -1,26 +0,0 @@
import { Injectable } from '@nestjs/common';
import { CreateOutputDto } from './dto/create-output.dto';
import { UpdateOutputDto } from './dto/update-output.dto';
@Injectable()
export class OutputsService {
create(createOutputDto: CreateOutputDto) {
return 'This action adds a new output';
}
list() {
return `This action returns all outputs`;
}
show(id: string) {
return `This action returns a #${id} output`;
}
update(id: string, updateOutputDto: UpdateOutputDto) {
return `This action updates a #${id} output`;
}
remove(id: string) {
return `This action removes a #${id} output`;
}
}
-48
View File
@@ -1,48 +0,0 @@
syntax = "proto3";
package output;
import "google/protobuf/timestamp.proto";
service OutputService{
rpc Create(CreateOutputRequest) returns (Output) {}
rpc Show(IdRequest) returns (Output) {}
rpc List(Empty) returns (ListResponse){}
rpc Update(UpdateOutputRequest) returns (Output){}
rpc Remove(IdRequest) returns (Empty){}
}
message Empty {}
message IdRequest{
string id = 1;
}
message Output {
string id = 1;
string name = 2;
string plugin = 3;
string values = 4;
string operation = 5;
}
message CreateOutputRequest {
string name = 1;
string plugin = 2;
string values = 3;
string operation = 4;
}
message UpdateOutputRequest{
string id = 1;
string name = 3;
string plugin = 4;
string values = 5;
string operation = 6;
}
message ListResponse {
repeated Output outputs = 1;
}
-17
View File
@@ -1,17 +0,0 @@
import { join } from 'path';
import { ClientOptions, Transport } from '@nestjs/microservices';
export const GrpcClientConfiguration: ClientOptions = {
transport: Transport.GRPC,
options: {
//url: `${process.env.USERS_SVC_URL}:${process.env.USERS_SVC_PORT}`,
url: `127.0.0.1:50054`,
package: 'pipeline',
protoPath: join(__dirname, '..', 'proto', 'pipeline.proto'),
loader: {
enums: String,
objects: true,
arrays: true,
},
},
};
-12
View File
@@ -1,12 +0,0 @@
import { InputGrpcClient } from "src/inputs/entities/input-grcp-client.entity";
import { Output } from "src/outputs/entities/output.entity";
import { Transformation } from "src/transformations/entities/transformation.entity";
export class CreatePipelineDto {
input:InputGrpcClient;
output:Output;
transformations:Transformation;
tags:string[];
name:string;
description:string;
}
-6
View File
@@ -1,6 +0,0 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreatePipelineDto } from './create-pipeline.dto';
export class UpdatePipelineDto extends PartialType(CreatePipelineDto) {
}
-14
View File
@@ -1,14 +0,0 @@
import { InputGrpcClient } from "src/inputs/entities/input-grcp-client.entity";
import { Output } from "src/outputs/entities/output.entity";
import { Transformation } from "src/transformations/entities/transformation.entity";
export class Pipeline {
id:string;
input:InputGrpcClient;
output:Output;
transformations:Transformation;
tags:string[];
name:string;
description:string;
status:string;
}
@@ -1,20 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PipelinesController } from './pipelines.controller';
import { PipelinesService } from './pipelines.service';
describe('PipelinesController', () => {
let controller: PipelinesController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [PipelinesController],
providers: [PipelinesService],
}).compile();
controller = module.get<PipelinesController>(PipelinesController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
-70
View File
@@ -1,70 +0,0 @@
import {
Controller,
Delete,
Get,
OnModuleInit,
Param,
Post,
Put,
} from '@nestjs/common';
import {
Client,
ClientGrpc,
MessagePattern,
Payload,
} from '@nestjs/microservices';
import { PipelinesService } from './pipelines.service';
import { CreatePipelineDto } from './dto/create-pipeline.dto';
import { UpdatePipelineDto } from './dto/update-pipeline.dto';
import { GrpcClientConfiguration } from './config/grpc-client';
@Controller('pipeline')
export class PipelinesController implements OnModuleInit {
@Client(GrpcClientConfiguration)
private pipelineServiceClient: ClientGrpc;
private pipelineService: PipelinesService;
onModuleInit() {
this.pipelineService =
this.pipelineServiceClient.getService<PipelinesService>(
'PipelineService',
);
}
@Post()
create(@Payload() createPipelineDto: CreatePipelineDto) {
return this.pipelineService.create(createPipelineDto);
}
@Get()
list() {
return this.pipelineService.list();
}
@Get(':id')
show(@Param() id: string) {
return this.pipelineService.show(id);
}
@Put(':id')
update(@Param() id: string, @Payload() updatePipelineDto: UpdatePipelineDto) {
return this.pipelineService.update(id, updatePipelineDto);
}
@Delete()
remove(@Param() id: string) {
return this.pipelineService.remove(id);
}
@Post()
getPipelineLogsMessages(@Param() id: string, @Payload() details: string) {
return this.pipelineService.getPipelineLogsMessages(id, details);
}
getPipelineStatus(id: string) {
return this.pipelineService.getPipelineStatus(id);
}
}
-9
View File
@@ -1,9 +0,0 @@
import { Module } from '@nestjs/common';
import { PipelinesService } from './pipelines.service';
import { PipelinesController } from './pipelines.controller';
@Module({
controllers: [PipelinesController],
providers: [PipelinesService],
})
export class PipelinesModule {}
-18
View File
@@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PipelinesService } from './pipelines.service';
describe('PipelinesService', () => {
let service: PipelinesService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [PipelinesService],
}).compile();
service = module.get<PipelinesService>(PipelinesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
-34
View File
@@ -1,34 +0,0 @@
import { Injectable } from '@nestjs/common';
import { CreatePipelineDto } from './dto/create-pipeline.dto';
import { UpdatePipelineDto } from './dto/update-pipeline.dto';
@Injectable()
export class PipelinesService {
create(createPipelineDto: CreatePipelineDto) {
return 'This action adds a new pipeline';
}
list() {
return `This action returns all pipelines`;
}
show(id: string) {
return `This action returns a #${id} pipeline`;
}
update(id: string, updatePipelineDto: UpdatePipelineDto) {
return `This action updates a #${id} pipeline`;
}
remove(id: string) {
return `This action removes a #${id} pipeline`;
}
getPipelineLogsMessages(id: string, details: string) {
return `This action perfoms a getLogMessages on #${id} pipeline`;
}
getPipelineStatus(id: string) {
return `This action performs a getStatus on #${id} pipeline`;
}
}
-97
View File
@@ -1,97 +0,0 @@
syntax = "proto3";
package pipeline;
import "google/protobuf/timestamp.proto";
service PipelineService{
rpc Create(CreatePipelineRequest) returns (Pipeline) {}
rpc Show(IdRequest) returns (Pipeline) {}
rpc List(Empty) returns (ListResponse){}
rpc Update(UpdatePipelineRequest) returns (Pipeline){}
rpc Remove(IdRequest) returns (Empty){}
rpc getPipelineLogsMessages(getPipelineLogsMessagesRequest) returns (getPipelineLogsMessagesResponse){}
rpc getPipelineStatus(IdRequest) returns (getPipelineStatusResponse){}
}
message Empty {}
message IdRequest{
string id = 1;
}
message Transformation {
string id = 1;
string inputSource = 2;
string table = 3;
string type = 4;
string params = 5;
}
message Input {
string id = 1;
string cronFormated = 2;
string name = 3;
string plugin = 4;
string values = 5;
string operation = 6;
}
message Output {
string id = 1;
string name = 2;
string plugin = 3;
string values = 4;
string operation = 5;
}
message Pipeline {
string id = 1;
Input input = 2;
Output output = 3;
Transformation transformations = 4;
repeated string tags = 5;
string name = 6;
string description = 7;
string status = 8;
}
message CreatePipelineRequest {
Input input = 1;
Output output = 2;
Transformation transformations = 3;
repeated string tags = 4;
string name = 5;
string description = 6;
}
message UpdatePipelineRequest{
string id = 1;
repeated string tags = 2;
string name = 3;
string description = 4;
string status = 5;
}
message ListResponse {
repeated Pipeline pipelines = 1;
}
message getPipelineLogsMessagesRequest{
string id = 1;
string details = 2;
}
message getPipelineLogsMessagesResponseItem{
string date = 1;
string log = 2;
}
message getPipelineLogsMessagesResponse{
repeated getPipelineLogsMessagesResponseItem pipelineLogs = 1;
}
message getPipelineStatusResponse{
string status = 1;
}
@@ -1,6 +0,0 @@
export class CreateRestEnrichmentDto {
type:string;
columns
}
@@ -1,4 +0,0 @@
import { PartialType } from '@nestjs/swagger';
import { CreateRestEnrichmentDto } from './create-rest-enrichment.dto';
export class UpdateRestEnrichmentDto extends PartialType(CreateRestEnrichmentDto) {}
@@ -1,7 +0,0 @@
export class RestEnrichment {
id:string;
type:string;
columns:string[]
}
@@ -1,20 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RestEnrichmentsController } from './rest-enrichments.controller';
import { RestEnrichmentsService } from './rest-enrichments.service';
describe('RestEnrichmentsController', () => {
let controller: RestEnrichmentsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [RestEnrichmentsController],
providers: [RestEnrichmentsService],
}).compile();
controller = module.get<RestEnrichmentsController>(RestEnrichmentsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

Some files were not shown because too many files have changed in this diff Show More