├── .gitignore
├── .gitpod.yml
├── .vscode
└── settings.json
├── README.md
├── astra.json
├── img
└── splash.png
├── week1-intro-to-cassandra
├── LICENSE
├── README.MD
├── images
│ ├── astra-cql-console.gif
│ ├── astra-create-2.png
│ ├── astra-create-3.png
│ ├── astra-create-4.png
│ ├── astra-create-5.png
│ ├── astra-create-6.png
│ ├── astra-create-7.png
│ ├── astra-create-launch-now.png
│ ├── astra-create-login.png
│ ├── astra-create-register.png
│ ├── astra-login-cql-console.png
│ ├── astra-use-cql-console-create-tables.png
│ ├── astra-use-cql-console-create-users-by-city.png
│ ├── astra-use-cql-console-delete-from-comments-by-video.png
│ ├── astra-use-cql-console-delete-from-cred.png
│ ├── astra-use-cql-console-desc-keyspace.png
│ ├── astra-use-cql-console-describe-tables.png
│ ├── astra-use-cql-console-insert-into-cred.png
│ ├── astra-use-cql-console-select-from-tables.png
│ ├── astra-use-cql-console-update-comments-by-video.png
│ ├── astra-use-cql-console-use-killrvideo.png
│ ├── astra-use-cql-console.png
│ ├── astra-view-cql-console.png
│ ├── badge
│ │ └── intro-to-cassandra.png
│ ├── cluster_basics.png
│ ├── cql
│ │ ├── 01_desc_keyspaces.png
│ │ ├── 02_use_chatsandra.png
│ │ ├── 03_user_table_created.png
│ │ ├── 04_post_tables_created.png
│ │ ├── 05_selects.png
│ │ ├── 06_updated.png
│ │ └── 07_deleting.png
│ ├── getting-started-with-cassandra.png
│ ├── intro.png
│ └── tutorials
│ │ ├── astra-create-db.gif
│ │ └── astra_signup.gif
└── slides
│ ├── Presentation.pdf
│ └── WEEK1 - Introduction to Apache Cassandra.pdf
├── week2-data-modelling
├── README.md
├── images
│ ├── astra-cql-console.gif
│ ├── create_keyspace_todos.gif
│ ├── data_model_methodology_badge.png
│ ├── datamodel.png
│ ├── killrvideo_users_by_city.png
│ ├── resuming.png
│ ├── resuming2.png
│ ├── sensors-1-er.png
│ ├── sensors-2-aw.png
│ ├── sensors-3-ld.png
│ ├── sensors-4-pd.png
│ ├── shopping-cart-data-access-patterns.png
│ ├── todoapp.png
│ └── todoitems_table_created.png
├── model.cql
└── slides
│ ├── Presentation.pdf
│ └── test
├── week3-app-development
├── .env.sample
├── README.MD
├── images
│ ├── AppDevSplash.png
│ ├── Filexplorer0.png
│ ├── OpenPorts.png
│ ├── Verifytodos.png
│ ├── allow.png
│ ├── api_badge.png
│ ├── appdev_badge.png
│ ├── astra-create-token.gif
│ ├── astra-token.png
│ ├── bootcamp_badge.png
│ ├── dotenv1.png
│ ├── dotenv2.png
│ ├── dotenv3.png
│ ├── dotenv4.png
│ ├── dotenv5.png
│ ├── gitpod-01-home-annotated.png
│ ├── gitpod-01-home-plain.png
│ ├── gitpod-02-url.png
│ ├── gitpod-bootcampappdev-1.jpg
│ ├── gitpodpreferences1.png
│ ├── secureconnectbundle1.png
│ ├── secureconnectbundle2.png
│ ├── secureconnectbundle3.png
│ └── shells.png
├── java
│ ├── README.MD
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── datastax
│ │ │ └── workshop
│ │ │ ├── DBConnection.java
│ │ │ └── DBConnection.java.init
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── datastax
│ │ │ └── workshop
│ │ │ ├── Ex06_Connect_to_Astra.java
│ │ │ ├── Ex6a_Create_Table.java
│ │ │ ├── Ex6b_Insert_Todos.java
│ │ │ ├── Ex6c_Get_All_Todos.java
│ │ │ ├── Ex6d_Update_A_Todo.java
│ │ │ ├── Ex6e_Remove_A_Todo.java
│ │ │ ├── Ex6f_Remove_All_Todos.java
│ │ │ └── TestUtils.java
│ │ └── resources
│ │ └── logback-test.xml
├── javascript
│ ├── Ex06_Connect_to_Astra.js
│ ├── Ex6a_Create_Table.js
│ ├── Ex6b_Insert_Todos.js
│ ├── Ex6c_Get_All_Todos.js
│ ├── Ex6d_Update_A_Todo.js
│ ├── Ex6e_Remove_A_Todo.js
│ ├── Ex6f_Remove_All_Todos.js
│ ├── README.MD
│ ├── connection.js
│ └── connection.js.init
├── plugastracreds
├── python
│ ├── Ex06_Connect_to_Astra.py
│ ├── Ex6a_Create_Table.py
│ ├── Ex6b_Insert_Todos.py
│ ├── Ex6c_Get_All_Todos.py
│ ├── Ex6d_Update_A_Todo.py
│ ├── Ex6e_Remove_A_Todo.py
│ ├── Ex6f_Remove_All_Todos.py
│ ├── README.MD
│ ├── connection.py
│ └── connection.py.init
└── slides
│ └── WEEK3 - App Development with Cassandra.pdf
└── week4-api-microservices
├── .env.sample
├── README.MD
├── images
├── Filexplorer0.png
├── OpenPorts.png
├── Verifytodos.png
├── allow.png
├── astra-create-token.gif
├── astra-token.png
├── bootcamp_badge.png
├── dotenv1.png
├── dotenv2.png
├── dotenv3.png
├── dotenv4.png
├── dotenv5.png
├── gitpod-01-home-annotated.png
├── gitpod-01-home-plain.png
├── gitpod-02-url.png
├── gitpod-bootcampappdev-1.jpg
├── gitpod-client-error.png
├── gitpod-client-success.png
├── gitpod-home-error.png
├── gitpod-john-task.png
├── gitpod-openport.png
├── gitpod-spec-error.png
├── gitpod-spec-success.png
├── gitpodpreferences1.png
├── public9191.png
├── resume-db.png
├── secureconnectbundle1.png
├── secureconnectbundle2.png
├── secureconnectbundle3.png
├── shells.png
├── splash.png
├── todobackend-output-client.png
├── todobackend-output-host.png
├── todobackend-runclient.png
├── todobackend-runtest.png
├── todobackend.png
├── todobackend2-1.png
├── todomvc.png
└── week4_badge.png
├── java
├── README.MD
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── datastaxdev
│ │ │ ├── TodoApplication.java
│ │ │ ├── conf
│ │ │ └── CassandraDriverConguration.java
│ │ │ └── todo
│ │ │ ├── Todo.java
│ │ │ ├── TodoItem.java
│ │ │ ├── TodoItemKey.java
│ │ │ ├── TodoItemRepository.java
│ │ │ └── TodoRestController.java
│ └── resources
│ │ ├── META-INF
│ │ └── additional-spring-configuration-metadata.json
│ │ ├── application.conf
│ │ ├── application.properties
│ │ ├── application.properties.init
│ │ ├── banner.txt
│ │ └── logback.xml
│ └── test
│ └── java
│ └── com
│ └── datastaxdev
│ ├── Test01_Connect.java
│ ├── Test02_CreateSchema.java
│ ├── Test03_SaveTask.java
│ └── Test04_Controller.java
├── javascript
├── .env.example
├── README.MD
├── Test01_Connect.js
├── Test02_CreateSchema.js
├── Test03_SaveTask.js
├── api.js
├── connection.js
├── connection.js.init
├── package-lock.json
├── package.json
├── todos.js
└── todos.test.js
├── plugastracreds
├── python
├── .env.example
├── README.MD
├── Test01_Connect.py
├── Test02_CreateSchema.py
├── Test03_SaveTask.py
├── api.py
├── connection.py
├── connection.py.init
├── pytest.ini
├── requirements.txt
├── test_api.py
├── test_todos.py
└── todos.py
└── slides
└── slides.pdf
/.gitignore:
--------------------------------------------------------------------------------
1 | bundle.zip
2 |
3 | ############################
4 | # JAVA
5 | ############################
6 |
7 | # eclipse conf file
8 | .settings
9 | .classpath
10 | .project
11 | .cache
12 | .factorypath
13 |
14 | # idea conf files
15 | .idea
16 | *.ipr
17 | *.iws
18 | *.iml
19 |
20 | # building
21 | target
22 | # build
23 | tmp
24 | dist
25 |
26 |
27 | ############################
28 | # PYTHON
29 | ############################
30 |
31 | # Byte-compiled / optimized / DLL files
32 | __pycache__/
33 | *.py[cod]
34 | *$py.class
35 |
36 | # C extensions
37 | *.so
38 |
39 | # Distribution / packaging
40 | .Python
41 | # build/
42 | develop-eggs/
43 | dist/
44 | downloads/
45 | eggs/
46 | .eggs/
47 | lib/
48 | lib64/
49 | parts/
50 | sdist/
51 | var/
52 | wheels/
53 | pip-wheel-metadata/
54 | share/python-wheels/
55 | *.egg-info/
56 | .installed.cfg
57 | *.egg
58 | MANIFEST
59 |
60 | # PyInstaller
61 | # Usually these files are written by a python script from a template
62 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
63 | *.manifest
64 | *.spec
65 |
66 | # Installer logs
67 | pip-log.txt
68 | pip-delete-this-directory.txt
69 |
70 | # Unit test / coverage reports
71 | htmlcov/
72 | .tox/
73 | .nox/
74 | .coverage
75 | .coverage.*
76 | .cache
77 | nosetests.xml
78 | coverage.xml
79 | *.cover
80 | .hypothesis/
81 | .pytest_cache/
82 |
83 | # Translations
84 | *.mo
85 | *.pot
86 |
87 | # Django stuff:
88 | *.log
89 | local_settings.py
90 | db.sqlite3
91 | db.sqlite3-journal
92 |
93 | # Flask stuff:
94 | instance/
95 | .webassets-cache
96 |
97 | # Scrapy stuff:
98 | .scrapy
99 |
100 | # Sphinx documentation
101 | docs/_build/
102 |
103 | # PyBuilder
104 | target/
105 |
106 | # Jupyter Notebook
107 | .ipynb_checkpoints
108 |
109 | # IPython
110 | profile_default/
111 | ipython_config.py
112 |
113 | # pyenv
114 | .python-version
115 |
116 | # pipenv
117 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
118 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
119 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
120 | # install all needed dependencies.
121 | #Pipfile.lock
122 |
123 | # celery beat schedule file
124 | celerybeat-schedule
125 |
126 | # SageMath parsed files
127 | *.sage.py
128 |
129 | # Environments
130 | .env
131 | .venv
132 | env/
133 | venv/
134 | ENV/
135 | env.bak/
136 | venv.bak/
137 |
138 | # Spyder project settings
139 | .spyderproject
140 | .spyproject
141 |
142 | # Rope project settings
143 | .ropeproject
144 |
145 | # mkdocs documentation
146 | /site
147 |
148 | # mypy
149 | .mypy_cache/
150 | .dmypy.json
151 | dmypy.json
152 |
153 | # Pyre type checker
154 | .pyre/
155 |
156 |
157 | ############################
158 | # NODEJS
159 | ############################
160 |
161 | # Logs
162 | logs
163 | *.log
164 | npm-debug.log*
165 | yarn-debug.log*
166 | yarn-error.log*
167 | lerna-debug.log*
168 |
169 | # Diagnostic reports (https://nodejs.org/api/report.html)
170 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
171 |
172 | # Runtime data
173 | pids
174 | *.pid
175 | *.seed
176 | *.pid.lock
177 |
178 | # Directory for instrumented libs generated by jscoverage/JSCover
179 | lib-cov
180 |
181 | # Coverage directory used by tools like istanbul
182 | coverage
183 | *.lcov
184 |
185 | # nyc test coverage
186 | .nyc_output
187 |
188 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
189 | .grunt
190 |
191 | # Bower dependency directory (https://bower.io/)
192 | bower_components
193 |
194 | # node-waf configuration
195 | .lock-wscript
196 |
197 | # Compiled binary addons (https://nodejs.org/api/addons.html)
198 | build/Release
199 |
200 | # Dependency directories
201 | node_modules/
202 | jspm_packages/
203 |
204 | # TypeScript v1 declaration files
205 | typings/
206 |
207 | # TypeScript cache
208 | *.tsbuildinfo
209 |
210 | # Optional npm cache directory
211 | .npm
212 |
213 | # Optional eslint cache
214 | .eslintcache
215 |
216 | # Optional REPL history
217 | .node_repl_history
218 |
219 | # Output of 'npm pack'
220 | *.tgz
221 |
222 | # Yarn Integrity file
223 | .yarn-integrity
224 |
225 | # dotenv environment variables file
226 | .env
227 | .env.test
228 |
229 | # parcel-bundler cache (https://parceljs.org/)
230 | .cache
231 |
232 | # next.js build output
233 | .next
234 |
235 | # nuxt.js build output
236 | .nuxt
237 |
238 | # vuepress build output
239 | .vuepress/dist
240 |
241 | # Serverless directories
242 | .serverless/
243 |
244 | # FuseBox cache
245 | .fusebox/
246 |
247 | # DynamoDB Local files
248 | .dynamodb/
249 |
250 |
251 | ## Ignore Visual Studio temporary files, build results, and
252 | ## files generated by popular Visual Studio add-ons.
253 | ##
254 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
255 |
256 | # User-specific files
257 | *.rsuser
258 | *.suo
259 | *.user
260 | *.userosscache
261 | *.sln.docstates
262 |
263 | # User-specific files (MonoDevelop/Xamarin Studio)
264 | *.userprefs
265 |
266 | # Mono auto generated files
267 | mono_crash.*
268 |
269 | # Build results
270 | [Dd]ebug/
271 | [Dd]ebugPublic/
272 | [Rr]elease/
273 | [Rr]eleases/
274 | x64/
275 | x86/
276 | [Aa][Rr][Mm]/
277 | [Aa][Rr][Mm]64/
278 | bld/
279 | [Bb]in/
280 | [Oo]bj/
281 | [Ll]og/
282 |
283 | # Visual Studio 2015/2017 cache/options directory
284 | .vs/
285 | # Uncomment if you have tasks that create the project's static files in wwwroot
286 | #wwwroot/
287 |
288 | # Visual Studio 2017 auto generated files
289 | Generated\ Files/
290 |
291 | # MSTest test Results
292 | [Tt]est[Rr]esult*/
293 | [Bb]uild[Ll]og.*
294 |
295 | # NUnit
296 | *.VisualState.xml
297 | TestResult.xml
298 | nunit-*.xml
299 |
300 | # Build Results of an ATL Project
301 | [Dd]ebugPS/
302 | [Rr]eleasePS/
303 | dlldata.c
304 |
305 | # Benchmark Results
306 | BenchmarkDotNet.Artifacts/
307 |
308 | # .NET Core
309 | project.lock.json
310 | project.fragment.lock.json
311 | artifacts/
312 |
313 | # StyleCop
314 | StyleCopReport.xml
315 |
316 | # Files built by Visual Studio
317 | *_i.c
318 | *_p.c
319 | *_h.h
320 | *.ilk
321 | *.meta
322 | *.obj
323 | *.iobj
324 | *.pch
325 | *.pdb
326 | *.ipdb
327 | *.pgc
328 | *.pgd
329 | *.rsp
330 | *.sbr
331 | *.tlb
332 | *.tli
333 | *.tlh
334 | *.tmp
335 | *.tmp_proj
336 | *_wpftmp.csproj
337 | *.log
338 | *.vspscc
339 | *.vssscc
340 | .builds
341 | *.pidb
342 | *.svclog
343 | *.scc
344 |
345 | # Chutzpah Test files
346 | _Chutzpah*
347 |
348 | # Visual C++ cache files
349 | ipch/
350 | *.aps
351 | *.ncb
352 | *.opendb
353 | *.opensdf
354 | *.sdf
355 | *.cachefile
356 | *.VC.db
357 | *.VC.VC.opendb
358 |
359 | # Visual Studio profiler
360 | *.psess
361 | *.vsp
362 | *.vspx
363 | *.sap
364 |
365 | # Visual Studio Trace Files
366 | *.e2e
367 |
368 | # TFS 2012 Local Workspace
369 | $tf/
370 |
371 | # Guidance Automation Toolkit
372 | *.gpState
373 |
374 | # ReSharper is a .NET coding add-in
375 | _ReSharper*/
376 | *.[Rr]e[Ss]harper
377 | *.DotSettings.user
378 |
379 | # JustCode is a .NET coding add-in
380 | .JustCode
381 |
382 | # TeamCity is a build add-in
383 | _TeamCity*
384 |
385 | # DotCover is a Code Coverage Tool
386 | *.dotCover
387 |
388 | # AxoCover is a Code Coverage Tool
389 | .axoCover/*
390 | !.axoCover/settings.json
391 |
392 | # Visual Studio code coverage results
393 | *.coverage
394 | *.coveragexml
395 |
396 | # NCrunch
397 | _NCrunch_*
398 | .*crunch*.local.xml
399 | nCrunchTemp_*
400 |
401 | # MightyMoose
402 | *.mm.*
403 | AutoTest.Net/
404 |
405 | # Web workbench (sass)
406 | .sass-cache/
407 |
408 | # Installshield output folder
409 | [Ee]xpress/
410 |
411 | # DocProject is a documentation generator add-in
412 | DocProject/buildhelp/
413 | DocProject/Help/*.HxT
414 | DocProject/Help/*.HxC
415 | DocProject/Help/*.hhc
416 | DocProject/Help/*.hhk
417 | DocProject/Help/*.hhp
418 | DocProject/Help/Html2
419 | DocProject/Help/html
420 |
421 | # Click-Once directory
422 | publish/
423 |
424 | # Publish Web Output
425 | *.[Pp]ublish.xml
426 | *.azurePubxml
427 | # Note: Comment the next line if you want to checkin your web deploy settings,
428 | # but database connection strings (with potential passwords) will be unencrypted
429 | *.pubxml
430 | *.publishproj
431 |
432 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
433 | # checkin your Azure Web App publish settings, but sensitive information contained
434 | # in these scripts will be unencrypted
435 | PublishScripts/
436 |
437 | # NuGet Packages
438 | *.nupkg
439 | # NuGet Symbol Packages
440 | *.snupkg
441 | # The packages folder can be ignored because of Package Restore
442 | **/[Pp]ackages/*
443 | # except build/, which is used as an MSBuild target.
444 | !**/[Pp]ackages/build/
445 | # Uncomment if necessary however generally it will be regenerated when needed
446 | #!**/[Pp]ackages/repositories.config
447 | # NuGet v3's project.json files produces more ignorable files
448 | *.nuget.props
449 | *.nuget.targets
450 |
451 | # Microsoft Azure Build Output
452 | csx/
453 | *.build.csdef
454 |
455 | # Microsoft Azure Emulator
456 | ecf/
457 | rcf/
458 |
459 | # Windows Store app package directories and files
460 | AppPackages/
461 | BundleArtifacts/
462 | Package.StoreAssociation.xml
463 | _pkginfo.txt
464 | *.appx
465 | *.appxbundle
466 | *.appxupload
467 |
468 |
469 | ############################
470 | # CSHARP
471 | ############################
472 |
473 | !?*.[Cc]ache/
474 |
475 | # Others
476 | ClientBin/
477 | ~$*
478 | *~
479 | *.dbmdl
480 | *.dbproj.schemaview
481 | *.jfm
482 | *.pfx
483 | *.publishsettings
484 | orleans.codegen.cs
485 |
486 | # Including strong name files can present a security risk
487 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
488 | #*.snk
489 |
490 | # Since there are multiple workflows, uncomment next line to ignore bower_components
491 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
492 | #bower_components/
493 |
494 | # RIA/Silverlight projects
495 | Generated_Code/
496 |
497 | # Backup & report files from converting an old project file
498 | # to a newer Visual Studio version. Backup files are not needed,
499 | # because we have git ;-)
500 | _UpgradeReport_Files/
501 | Backup*/
502 | UpgradeLog*.XML
503 | UpgradeLog*.htm
504 | ServiceFabricBackup/
505 | *.rptproj.bak
506 |
507 | # SQL Server files
508 | *.mdf
509 | *.ldf
510 | *.ndf
511 |
512 | # Business Intelligence projects
513 | *.rdl.data
514 | *.bim.layout
515 | *.bim_*.settings
516 | *.rptproj.rsuser
517 | *- [Bb]ackup.rdl
518 | *- [Bb]ackup ([0-9]).rdl
519 | *- [Bb]ackup ([0-9][0-9]).rdl
520 |
521 | # Microsoft Fakes
522 | FakesAssemblies/
523 |
524 | # GhostDoc plugin setting file
525 | *.GhostDoc.xml
526 |
527 | # Node.js Tools for Visual Studio
528 | .ntvs_analysis.dat
529 | node_modules/
530 |
531 | # Visual Studio 6 build log
532 | *.plg
533 |
534 | # Visual Studio 6 workspace options file
535 | *.opt
536 |
537 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
538 | *.vbw
539 |
540 | # Visual Studio LightSwitch build output
541 | **/*.HTMLClient/GeneratedArtifacts
542 | **/*.DesktopClient/GeneratedArtifacts
543 | **/*.DesktopClient/ModelManifest.xml
544 | **/*.Server/GeneratedArtifacts
545 | **/*.Server/ModelManifest.xml
546 | _Pvt_Extensions
547 |
548 | # Paket dependency manager
549 | .paket/paket.exe
550 | paket-files/
551 |
552 | # FAKE - F# Make
553 | .fake/
554 |
555 | # CodeRush personal settings
556 | .cr/personal
557 |
558 | # Python Tools for Visual Studio (PTVS)
559 | __pycache__/
560 | *.pyc
561 |
562 | # Cake - Uncomment if you are using it
563 | # tools/**
564 | # !tools/packages.config
565 |
566 | # Tabs Studio
567 | *.tss
568 |
569 | # Telerik's JustMock configuration file
570 | *.jmconfig
571 |
572 | # BizTalk build output
573 | *.btp.cs
574 | *.btm.cs
575 | *.odx.cs
576 | *.xsd.cs
577 |
578 | # OpenCover UI analysis results
579 | OpenCover/
580 |
581 | # Azure Stream Analytics local run output
582 | ASALocalRun/
583 |
584 | # MSBuild Binary and Structured Log
585 | *.binlog
586 |
587 | # NVidia Nsight GPU debugger configuration file
588 | *.nvuser
589 |
590 | # MFractors (Xamarin productivity tool) working folder
591 | .mfractor/
592 |
593 | # Local History for Visual Studio
594 | .localhistory/
595 |
596 | # BeatPulse healthcheck temp database
597 | healthchecksdb
598 |
599 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
600 | MigrationBackup/
601 |
602 |
603 | ############################
604 | # MAC
605 | ############################
606 |
607 | .DS_Store
608 |
609 |
610 |
611 |
612 |
613 |
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | tasks:
2 | - name: setup
3 | env:
4 | CQLENG_ALLOW_SCHEMA_MANAGEMENT: 1
5 | FLASK_APP: api
6 | before: |
7 | echo "Setting up, please wait!"
8 | cd /workspace/bootcamp-fullstack-apps-with-cassandra
9 | sed -i '1,$s/sdkman_auto_answer=false/sdkman_auto_answer=true/' /home/gitpod/.sdkman/etc/config
10 | sed -i '1,$s/sdkman_selfupdate_enable=true/sdkman_selfupdate_enable=false/' /home/gitpod/.sdkman/etc/config
11 | sdk install java 21.2.0.r11-grl -y
12 | pip3 install cassandra-driver
13 | npm install cassandra-driver
14 | wget https://downloads.datastax.com/enterprise/cqlsh-astra.tar.gz \
15 | && tar xvzf cqlsh-astra.tar.gz \
16 | && rm -f cqlsh-astra.tar.gz
17 | cp ~/.zshrc ~/.zshrc.init
18 | if [ -f /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit ]; then
19 | cp /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit ~/.zshrc
20 | fi
21 | pip3 install -r week4-api-microservices/python/requirements.txt
22 | npm i --prefix week4-api-microservices/javascript
23 | ports:
24 | - port: 5005
25 | - port: 8080
26 | visibility: public
27 | - port: 8081
28 | onOpen: open-browser
29 | - port: 9191
30 | visibility: public
31 | onOpen: open-browser
32 |
33 | github:
34 | prebuilds:
35 | master: true
36 | branches: true
37 | pullRequests: true
38 | pullRequestsFromForks: false
39 | addCheck: true
40 | addComment: false
41 | addBadge: true
42 | addLabel: false
43 |
44 | vscode:
45 | extensions:
46 | - datastax.astra-for-vs-code
47 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "workbench.editor.enablePreviewFromCodeNavigation": true,
3 | "workbench.editor.enablePreviewFromQuickOpen": true,
4 | "workbench.editor.enablePreview": true,
5 | "workbench.editorAssociations": {
6 | "*.md": "vscode.markdown.preview.editor"
7 | },
8 | "terminal.integrated.profiles.linux": {
9 | "cqlsh": {
10 | "path": "zsh",
11 | "args": ["-l"],
12 | "overrideName": true
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Build FullStack Applications with Apache Cassandra
2 |
3 | ## 🎓🔥 Introduction to NotOnly SQL Databases
4 |
5 | [](http://www.apache.org/licenses/LICENSE-2.0)
6 | [](https://discord.com/widget?id=685554030159593522&theme=dark)
7 |
8 |
9 |
10 | * [Week I: Intro to Cassandra](https://github.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/tree/main/week1-intro-to-cassandra)
11 | * [Week II: Building Efficient Data Model with Apache Cassandra](https://github.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/tree/main/week2-data-modelling)
12 | * [Week III: Back End App Dev with Cassandra](week3-app-development)
13 | * [Week IV: APIs and Microservices with Cassandra](week4-api-microservices)
14 |
15 |
16 |
--------------------------------------------------------------------------------
/astra.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Build Microservice and API",
3 | "description": "Learn how to build a backend for Cassandra, from data model to drivers to API exposition",
4 | "duration": "120 minutes",
5 | "skillLevel": "Intermediate",
6 | "language":["java", "python", "javascript"],
7 | "stack": ["spring", "fastAPI", "express"],
8 | "githubUrl": "https://github.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra",
9 | "badge": "https://media.badgr.com/uploads/badges/ca43050e-5e6e-4edc-8218-3c12e66de4af.png",
10 | "youTubeUrl": [ "https://www.youtube.com/watch?v=4djnV5wZSeg",
11 | "https://www.youtube.com/watch?v=8KmSN3KEspE",
12 | "https://www.youtube.com/watch?v=sGBFNDvk0pA",
13 | "https://www.youtube.com/watch?v=h7BEsnMk1_E"
14 | ],
15 | "tags": [
16 | { "name": "java" },
17 | { "name": "javascript" },
18 | { "name": "python" },
19 | { "name": "api" },
20 | { "name":"astradb" },
21 | { "name":"cassandra" }
22 | ],
23 | "category": "workshop",
24 | "usecases": []
25 | }
26 |
--------------------------------------------------------------------------------
/img/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/img/splash.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-cql-console.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-cql-console.gif
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-2.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-3.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-4.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-5.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-6.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-7.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-launch-now.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-launch-now.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-login.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-create-register.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-create-register.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-login-cql-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-login-cql-console.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-create-tables.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-create-tables.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-create-users-by-city.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-create-users-by-city.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-delete-from-comments-by-video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-delete-from-comments-by-video.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-delete-from-cred.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-delete-from-cred.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-desc-keyspace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-desc-keyspace.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-describe-tables.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-describe-tables.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-insert-into-cred.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-insert-into-cred.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-select-from-tables.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-select-from-tables.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-update-comments-by-video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-update-comments-by-video.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console-use-killrvideo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console-use-killrvideo.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-use-cql-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-use-cql-console.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/astra-view-cql-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/astra-view-cql-console.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/badge/intro-to-cassandra.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/badge/intro-to-cassandra.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/cluster_basics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/cluster_basics.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/cql/01_desc_keyspaces.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/cql/01_desc_keyspaces.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/cql/02_use_chatsandra.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/cql/02_use_chatsandra.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/cql/03_user_table_created.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/cql/03_user_table_created.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/cql/04_post_tables_created.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/cql/04_post_tables_created.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/cql/05_selects.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/cql/05_selects.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/cql/06_updated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/cql/06_updated.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/cql/07_deleting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/cql/07_deleting.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/getting-started-with-cassandra.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/getting-started-with-cassandra.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/intro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/intro.png
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/tutorials/astra-create-db.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/tutorials/astra-create-db.gif
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/images/tutorials/astra_signup.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/images/tutorials/astra_signup.gif
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/slides/Presentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/slides/Presentation.pdf
--------------------------------------------------------------------------------
/week1-intro-to-cassandra/slides/WEEK1 - Introduction to Apache Cassandra.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week1-intro-to-cassandra/slides/WEEK1 - Introduction to Apache Cassandra.pdf
--------------------------------------------------------------------------------
/week2-data-modelling/images/astra-cql-console.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/astra-cql-console.gif
--------------------------------------------------------------------------------
/week2-data-modelling/images/create_keyspace_todos.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/create_keyspace_todos.gif
--------------------------------------------------------------------------------
/week2-data-modelling/images/data_model_methodology_badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/data_model_methodology_badge.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/datamodel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/datamodel.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/killrvideo_users_by_city.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/killrvideo_users_by_city.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/resuming.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/resuming.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/resuming2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/resuming2.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/sensors-1-er.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/sensors-1-er.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/sensors-2-aw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/sensors-2-aw.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/sensors-3-ld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/sensors-3-ld.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/sensors-4-pd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/sensors-4-pd.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/shopping-cart-data-access-patterns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/shopping-cart-data-access-patterns.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/todoapp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/todoapp.png
--------------------------------------------------------------------------------
/week2-data-modelling/images/todoitems_table_created.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/images/todoitems_table_created.png
--------------------------------------------------------------------------------
/week2-data-modelling/model.cql:
--------------------------------------------------------------------------------
1 | CREATE TABLE todoitems (
2 | user_id TEXT,
3 | item_id TIMEUUID,
4 | title TEXT,
5 | completed BOOLEAN,
6 | PRIMARY KEY ((user_id), item_id)
7 | ) WITH CLUSTERING ORDER BY (item_id ASC);
8 |
--------------------------------------------------------------------------------
/week2-data-modelling/slides/Presentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week2-data-modelling/slides/Presentation.pdf
--------------------------------------------------------------------------------
/week2-data-modelling/slides/test:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/week3-app-development/.env.sample:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #TODO: REPLACE_ME with Astra Client Id and Secret
3 |
4 | export ASTRA_USERNAME=
5 | export ASTRA_PASSWORD=
6 |
--------------------------------------------------------------------------------
/week3-app-development/images/AppDevSplash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/AppDevSplash.png
--------------------------------------------------------------------------------
/week3-app-development/images/Filexplorer0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/Filexplorer0.png
--------------------------------------------------------------------------------
/week3-app-development/images/OpenPorts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/OpenPorts.png
--------------------------------------------------------------------------------
/week3-app-development/images/Verifytodos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/Verifytodos.png
--------------------------------------------------------------------------------
/week3-app-development/images/allow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/allow.png
--------------------------------------------------------------------------------
/week3-app-development/images/api_badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/api_badge.png
--------------------------------------------------------------------------------
/week3-app-development/images/appdev_badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/appdev_badge.png
--------------------------------------------------------------------------------
/week3-app-development/images/astra-create-token.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/astra-create-token.gif
--------------------------------------------------------------------------------
/week3-app-development/images/astra-token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/astra-token.png
--------------------------------------------------------------------------------
/week3-app-development/images/bootcamp_badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/bootcamp_badge.png
--------------------------------------------------------------------------------
/week3-app-development/images/dotenv1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/dotenv1.png
--------------------------------------------------------------------------------
/week3-app-development/images/dotenv2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/dotenv2.png
--------------------------------------------------------------------------------
/week3-app-development/images/dotenv3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/dotenv3.png
--------------------------------------------------------------------------------
/week3-app-development/images/dotenv4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/dotenv4.png
--------------------------------------------------------------------------------
/week3-app-development/images/dotenv5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/dotenv5.png
--------------------------------------------------------------------------------
/week3-app-development/images/gitpod-01-home-annotated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/gitpod-01-home-annotated.png
--------------------------------------------------------------------------------
/week3-app-development/images/gitpod-01-home-plain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/gitpod-01-home-plain.png
--------------------------------------------------------------------------------
/week3-app-development/images/gitpod-02-url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/gitpod-02-url.png
--------------------------------------------------------------------------------
/week3-app-development/images/gitpod-bootcampappdev-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/gitpod-bootcampappdev-1.jpg
--------------------------------------------------------------------------------
/week3-app-development/images/gitpodpreferences1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/gitpodpreferences1.png
--------------------------------------------------------------------------------
/week3-app-development/images/secureconnectbundle1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/secureconnectbundle1.png
--------------------------------------------------------------------------------
/week3-app-development/images/secureconnectbundle2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/secureconnectbundle2.png
--------------------------------------------------------------------------------
/week3-app-development/images/secureconnectbundle3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/secureconnectbundle3.png
--------------------------------------------------------------------------------
/week3-app-development/images/shells.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/images/shells.png
--------------------------------------------------------------------------------
/week3-app-development/java/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.datastax.workshop
7 | crud
8 | 1.0-SNAPSHOT
9 | jar
10 |
11 |
12 | UTF-8
13 | 11
14 |
15 | 4.13.0
16 |
17 | 5.6.2
18 | 1.6.2
19 | 1.2.3
20 |
21 |
22 |
23 |
24 | com.datastax.oss
25 | java-driver-core
26 | ${cassandra-java-driver.version}
27 |
28 |
29 | com.datastax.oss
30 | java-driver-query-builder
31 | ${cassandra-java-driver.version}
32 |
33 |
34 | com.datastax.oss
35 | java-driver-mapper-runtime
36 | ${cassandra-java-driver.version}
37 |
38 |
39 | com.datastax.oss
40 | java-driver-mapper-processor
41 | ${cassandra-java-driver.version}
42 |
43 |
44 |
45 |
46 | org.junit.jupiter
47 | junit-jupiter-api
48 | ${junit.jupiter.version}
49 | test
50 |
51 |
52 | org.junit.jupiter
53 | junit-jupiter-engine
54 | ${junit.jupiter.version}
55 | test
56 |
57 |
58 | org.junit.platform
59 | junit-platform-runner
60 | ${junit.platform.version}
61 | test
62 |
63 |
64 | ch.qos.logback
65 | logback-classic
66 | ${logback.version}
67 |
68 |
69 |
70 |
71 |
72 |
73 | org.apache.maven.plugins
74 | maven-compiler-plugin
75 | 3.8.1
76 |
77 | ${java.version}
78 | ${java.version}
79 | ${java.version}
80 | false
81 |
82 |
83 | com.datastax.oss
84 | java-driver-mapper-processor
85 | ${cassandra-java-driver.version}
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/main/java/com/datastax/workshop/DBConnection.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | /*
4 | * WARNING: THIS FILE IS GOING TO BE OVERWRITTEN
5 | * you used when you created the ASTRA instance.
6 | */
7 | public interface DBConnection {
8 |
9 | // This is the Zip file you downloaded
10 | String SECURE_CONNECT_BUNDLE = "/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip";
11 |
12 | // This is the "Client Id" value you obtained earlier
13 | String USERNAME = "$ASTRA_USERNAME";
14 |
15 | // This is the "Client Secret" value you obtained earlier
16 | String PASSWORD = "$ASTRA_PASSWORD";
17 |
18 | // This is the keyspace name, recommended value was killrvideo
19 | String KEYSPACE = "todos";
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/main/java/com/datastax/workshop/DBConnection.java.init:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | /*
4 | *
5 | * THIS FILE WILL BE OVERWRITTEN. DO NOT MAKE ANY CHANGES HERE.
6 | */
7 | public interface DBConnection {
8 |
9 | // This is the Zip file you downloaded
10 | String SECURE_CONNECT_BUNDLE = "/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip";
11 |
12 | // This is the "Client Id" value you obtained earlier
13 | String USERNAME = "$ASTRA_USERNAME";
14 |
15 | // This is the "Client Secret" value you obtained earlier
16 | String PASSWORD = "$ASTRA_PASSWORD";
17 |
18 | // This is the keyspace name, recommended value was killrvideo
19 | String KEYSPACE = "todos";
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/java/com/datastax/workshop/Ex06_Connect_to_Astra.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | import java.io.File;
4 | import java.nio.file.Paths;
5 |
6 | import org.junit.jupiter.api.Assertions;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.platform.runner.JUnitPlatform;
9 | import org.junit.runner.RunWith;
10 |
11 | import com.datastax.oss.driver.api.core.CqlSession;
12 |
13 | @RunWith(JUnitPlatform.class)
14 | public class Ex06_Connect_to_Astra {
15 |
16 | @Test
17 | public void should_connect_to_astra() {
18 | System.out.println("[should_connect_to_astra] ========================================");
19 | System.out.println("[should_connect_to_astra] Start Exercise");
20 | // Given
21 | Assertions.assertFalse(
22 | DBConnection.SECURE_CONNECT_BUNDLE.equals(""),
23 | "Please fill DBConnection class constants"
24 | );
25 | Assertions.assertFalse(
26 | DBConnection.KEYSPACE.equals(""),
27 | "Please fill DBConnection class constants"
28 | );
29 | Assertions.assertFalse(
30 | DBConnection.USERNAME.equals(""),
31 | "Please fill DBConnection class constants"
32 | );
33 | Assertions.assertFalse(
34 | DBConnection.PASSWORD.equals(""),
35 | "Please fill DBConnection class constants"
36 | );
37 | Assertions.assertTrue(
38 | new File(DBConnection.SECURE_CONNECT_BUNDLE).exists(),
39 | "File '" +
40 | DBConnection.SECURE_CONNECT_BUNDLE +
41 | "' has not been found\n" +
42 | "To run this sample you need to download the secure bundle file from ASTRA WebPage\n" +
43 | "More info here:"
44 | );
45 | System.out.println("[should_connect_to_astra] File '" + DBConnection.SECURE_CONNECT_BUNDLE + "' located");
46 |
47 | // When
48 | try (
49 | CqlSession cqlSession = CqlSession
50 | .builder()
51 | .withCloudSecureConnectBundle(
52 | Paths.get(DBConnection.SECURE_CONNECT_BUNDLE)
53 | )
54 | .withAuthCredentials(DBConnection.USERNAME, DBConnection.PASSWORD)
55 | .withKeyspace(DBConnection.KEYSPACE)
56 | .build()
57 | ) {
58 | // Then
59 | System.out.println("[should_connect_to_astra] Connected with Keyspace " + cqlSession.getKeyspace().get());
60 | }
61 | System.out.println("[should_connect_to_astra] [OK]");
62 | System.out.println("[should_connect_to_astra] ========================================");
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/java/com/datastax/workshop/Ex6a_Create_Table.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.junit.platform.runner.JUnitPlatform;
5 | import org.junit.runner.RunWith;
6 |
7 | import com.datastax.oss.driver.api.core.CqlSession;
8 |
9 | @RunWith(JUnitPlatform.class)
10 | public class Ex6a_Create_Table implements DBConnection {
11 |
12 | @Test
13 | public void should_create_a_table_1() {
14 | System.out.println("[should_create_a_table_1] ========================================");
15 | System.out.println("[should_create_a_table_1] Start exercise");
16 |
17 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
18 | String query =
19 | "CREATE TABLE IF NOT EXISTS todoitems (" +
20 | "user_id TEXT," +
21 | "item_id TIMEUUID," +
22 | "title TEXT," +
23 | "completed BOOLEAN," +
24 | "PRIMARY KEY ((user_id), item_id)" +
25 | ") WITH CLUSTERING ORDER BY (item_id ASC);";
26 | cqlSession.execute(query);
27 | }
28 |
29 | System.out.println("[should_create_a_table_1] [OK]");
30 | System.out.println("[should_create_a_table_1] ========================================");
31 | System.out.println();
32 | }
33 |
34 | @Test
35 | public void should_create_a_table_2() {
36 | System.out.println("[should_create_a_table_2] ========================================");
37 | System.out.println("[should_create_a_table_2] Start exercise");
38 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
39 | TestUtils.createTableTodoItem(cqlSession);
40 | }
41 | System.out.println("[should_create_a_table_2] [OK]");
42 | System.out.println("[should_create_a_table_2] ========================================");
43 | }
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/java/com/datastax/workshop/Ex6b_Insert_Todos.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | import java.util.UUID;
4 |
5 | import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
6 | import org.junit.jupiter.api.Order;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.TestMethodOrder;
9 | import org.junit.platform.runner.JUnitPlatform;
10 | import org.junit.runner.RunWith;
11 |
12 | import com.datastax.oss.driver.api.core.CqlSession;
13 | import com.datastax.oss.driver.api.core.cql.PreparedStatement;
14 | import com.datastax.oss.driver.api.core.cql.SimpleStatement;
15 | import com.datastax.oss.driver.api.core.uuid.Uuids;
16 |
17 | @RunWith(JUnitPlatform.class)
18 | @TestMethodOrder(OrderAnnotation.class)
19 | public class Ex6b_Insert_Todos implements DBConnection {
20 |
21 | @Test
22 | @Order(1)
23 | public void should_insert_todos_1() {
24 | System.out.println("[should_insert_todos_1] ========================================");
25 | System.out.println("[should_insert_todos_1] Start with static CQL");
26 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
27 | cqlSession.execute(
28 | "INSERT INTO todoitems (user_id, item_id, completed, title) " +
29 | "VALUES ( 'john', 11111111-5cff-11ec-be16-1fedb0dfd057, true, 'Walk the dog');"
30 | );
31 |
32 | System.out.println("[should_insert_todos_1] Task '11111111-5cff-11ec-be16-1fedb0dfd057' has been inserted");
33 | cqlSession.execute(
34 | "INSERT INTO todoitems (user_id, item_id, completed, title) " +
35 | "VALUES ( 'john', 22222222-5cff-11ec-be16-1fedb0dfd057, false, 'Have lunch tomorrow');"
36 | );
37 | System.out.println("[should_insert_todos_1] Task '22222222-5cff-11ec-be16-1fedb0dfd057' has been inserted");
38 | cqlSession.execute(
39 | "INSERT INTO todoitems (user_id, item_id, completed, title) " +
40 | "VALUES ( 'mary', 33333333-5cff-11ec-be16-1fedb0dfd057, true, 'Attend the workshop');"
41 | );
42 | System.out.println("[should_insert_todos_1] Task '33333333-5cff-11ec-be16-1fedb0dfd057' has been inserted");
43 | }
44 | System.out.println("[should_insert_todos_1] [OK]");
45 | System.out.println("[should_insert_todos_1] ========================================\n");
46 | }
47 |
48 | @Test
49 | @Order(2)
50 | public void should_create_task_cql() {
51 | System.out.println("[should_create_task_cql] ========================================");
52 | System.out.println("[should_create_task_cql] Start Exercise");
53 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
54 | cqlSession.execute(""
55 | + "INSERT INTO todoitems (user_id, item_id, title, completed) "
56 | + "VALUES('createTask'," + Uuids.timeBased() + ",'Task CQL',FALSE)");
57 | }
58 | System.out.println("[should_create_task_cql] [OK]");
59 | System.out.println("[should_create_task_cql] ========================================\n");
60 | }
61 |
62 | @Test
63 | @Order(3)
64 | public void should_insert_task_simple_position() {
65 | System.out.println("[should_insert_task_simple_position] ========================================");
66 | System.out.println("[should_insert_task_simple_position] Start Exercise");
67 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
68 | UUID itemId = Uuids.timeBased();
69 | cqlSession.execute(SimpleStatement.builder(""
70 | + "INSERT INTO todoitems (user_id, item_id, title, completed) "
71 | + "VALUES(?,?,?,?)")
72 | .addPositionalValue("createTask")
73 | .addPositionalValue(itemId)
74 | .addPositionalValue("Task Simple Statement position")
75 | .addPositionalValue(Boolean.FALSE)
76 | .build());
77 | System.out.println("[should_insert_task_simple_position] Task " + itemId + " has been inserted");
78 | }
79 | System.out.println("[should_insert_task_simple_position] [OK]");
80 | System.out.println("[should_insert_task_simple_position] ========================================\n");
81 | }
82 |
83 | @Test
84 | @Order(4)
85 | public void should_insert_task_simple_label() {
86 | System.out.println("[should_insert_task_simple_label] ========================================");
87 | System.out.println("[should_insert_task_simple_label] Start Exercise");
88 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
89 | UUID itemId = Uuids.timeBased();
90 | cqlSession.execute(SimpleStatement.builder(""
91 | + "INSERT INTO todoitems (user_id, item_id, title, completed) "
92 | + "VALUES(:userid,:itemid,:title,:completed)")
93 | .addNamedValue("userid","createTask")
94 | .addNamedValue("itemid",itemId)
95 | .addNamedValue("title","Task Simple Statement name")
96 | .addNamedValue("completed", Boolean.FALSE)
97 | .build());
98 | System.out.println("[should_insert_task_simple_label] Task " + itemId + " has been inserted");
99 | }
100 | System.out.println("[should_insert_task_simple_label] [OK]");
101 | System.out.println("[should_insert_task_simple_label] ========================================\n");
102 | }
103 |
104 | @Test
105 | @Order(5)
106 | public void should_insert_task_prepared() {
107 | System.out.println("[should_insert_task_prepared] ========================================");
108 | System.out.println("[should_insert_task_prepared] Start Exercise");
109 | // When
110 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
111 | PreparedStatement ps = cqlSession.prepare(
112 | "INSERT INTO todoitems (user_id, item_id, title, completed) "
113 | + "VALUES(?,?,?,?)");
114 | UUID itemId = Uuids.timeBased();
115 | cqlSession.execute(ps.bind("createTask", itemId, "Prepared Task", Boolean.FALSE));
116 | System.out.println("[should_insert_task_prepared] Task " + itemId + " has been inserted");
117 | }
118 | System.out.println("[should_insert_task_prepared] [OK]");
119 | System.out.println("[should_insert_task_prepared] ========================================\n");
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/java/com/datastax/workshop/Ex6c_Get_All_Todos.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
4 | import org.junit.jupiter.api.Order;
5 | import org.junit.jupiter.api.Test;
6 | import org.junit.jupiter.api.TestMethodOrder;
7 | import org.junit.platform.runner.JUnitPlatform;
8 | import org.junit.runner.RunWith;
9 |
10 | import com.datastax.oss.driver.api.core.CqlSession;
11 | import com.datastax.oss.driver.api.core.cql.ResultSet;
12 | import com.datastax.oss.driver.api.core.cql.Row;
13 | import com.datastax.oss.driver.api.core.cql.SimpleStatement;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 | import java.util.UUID;
18 |
19 | @RunWith(JUnitPlatform.class)
20 | @TestMethodOrder(OrderAnnotation.class)
21 | public class Ex6c_Get_All_Todos implements DBConnection {
22 |
23 | @Test
24 | @Order(1)
25 | public void should_get_todos_1() {
26 | System.out.println("[should_get_todos_1] ========================================");
27 | System.out.println("[should_get_todos_1] Looking for John's Tasks");
28 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
29 | ResultSet rs = cqlSession.execute(
30 | "SELECT * FROM todoitems WHERE user_id = 'john';"
31 | );
32 | for (Row row : rs) {
33 | System.out.println("[should_get_todos_1] " +
34 | row.getUuid("item_id") + ": " +
35 | row.getString("title"));
36 | }
37 | }
38 | System.out.println("[should_get_todos_1] [OK]");
39 | System.out.println("[should_get_todos_1] ========================================\n");
40 | }
41 |
42 | @Test
43 | @Order(2)
44 | public void should_get_todos_2() {
45 | System.out.println("[should_get_todos_2] ========================================");
46 | System.out.println("[should_get_todos_2] Looking for 'createTask' Tasks");
47 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
48 | SimpleStatement query = SimpleStatement.builder(""
49 | + "SELECT item_id,title,completed "
50 | + "FROM todoitems WHERE user_id=?")
51 | .addPositionalValue("createTask")
52 | .build();
53 | cqlSession.execute(query).forEach(row ->
54 | System.out.println("[should_get_todos_2] " +
55 | row.getUuid("item_id") + ": " +
56 | row.getString("title")));
57 | }
58 | System.out.println("[should_get_todos_2] [OK]");
59 | System.out.println("[should_get_todos_2] ========================================\n");
60 | }
61 | @Test
62 | @Order(3)
63 | public void should_get_todos_3() {
64 | class TodoItem {
65 | public String user_id;
66 | public UUID item_id;
67 | public String title;
68 | public Boolean completed;
69 |
70 | TodoItem(String u, UUID i, String t, Boolean c) {
71 | this.user_id = u;
72 | this.item_id = i;
73 | this.title = t;
74 | this.completed = c;
75 | }
76 | }
77 | System.out.println("[should_get_todos_3 with simple object mapper]=================");
78 | System.out.println("[should_get_todos_3] Looking for 'createTask' Tasks");
79 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
80 | ResultSet rs = cqlSession.execute(
81 | "SELECT * FROM todoitems WHERE user_id='createTask';"
82 | );
83 |
84 | List result = new ArrayList<>();
85 |
86 | // Simple Object Mapper
87 |
88 | rs.forEach(item -> result.add(
89 | new TodoItem(item.getString("user_id"),
90 | item.getUuid("item_id"),
91 | item.getString("title"),
92 | item.getBoolean("completed"))
93 | ));
94 |
95 | for (TodoItem item: result) {
96 | System.out.println("Todoitem title = " + item.title);
97 | }
98 | }
99 | System.out.println("[should_get_todos_3 with simple object mapper] [OK]");
100 | System.out.println("[should_get_todos_3] ========================================\n");
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/java/com/datastax/workshop/Ex6d_Update_A_Todo.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | import java.util.UUID;
4 |
5 | import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
6 | import org.junit.jupiter.api.Order;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.TestMethodOrder;
9 | import org.junit.platform.runner.JUnitPlatform;
10 | import org.junit.runner.RunWith;
11 |
12 | import com.datastax.oss.driver.api.core.CqlSession;
13 | import com.datastax.oss.driver.api.core.cql.SimpleStatement;
14 |
15 | @RunWith(JUnitPlatform.class)
16 | @TestMethodOrder(OrderAnnotation.class)
17 | public class Ex6d_Update_A_Todo implements DBConnection {
18 |
19 | @Test
20 | @Order(1)
21 | public void should_update_todos() {
22 | System.out.println("[should_update_todos] ========================================");
23 | System.out.println("[should_update_todos] Start Exercise");
24 | // When
25 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
26 | System.out.println("[should_update_todos] Before:");
27 | TestUtils.showTasks(cqlSession, "john");
28 | cqlSession.execute(""
29 | + "UPDATE todoitems "
30 | + "SET completed = true "
31 | + "WHERE user_id = 'john' "
32 | + "AND item_id = 22222222-5cff-11ec-be16-1fedb0dfd057;"
33 | );
34 | System.out.println("[should_update_todos] After:");
35 | TestUtils.showTasks(cqlSession, "john");
36 | }
37 | System.out.println("[should_update_todos] [OK]");
38 | System.out.println("[should_update_todos] ========================================\n");
39 | }
40 |
41 | @Test
42 | @Order(2)
43 | public void should_update_todos_2() {
44 | System.out.println("[should_update_todos_2] ========================================");
45 | System.out.println("[should_update_todos_2] Start Exercise");
46 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
47 | cqlSession.execute(SimpleStatement.builder(""
48 | + "UPDATE todoitems "
49 | + "SET completed=:flag "
50 | + "WHERE user_id=:userId AND item_id=:itemId")
51 | .addNamedValue("flag", false)
52 | .addNamedValue("userId", "john")
53 | .addNamedValue("itemId", UUID.fromString("11111111-5cff-11ec-be16-1fedb0dfd057"))
54 | .build());
55 | TestUtils.showTasks(cqlSession, "john");
56 | }
57 | System.out.println("[should_update_todos_2] [OK]");
58 | System.out.println("[should_update_todos_2] ========================================\n");
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/java/com/datastax/workshop/Ex6e_Remove_A_Todo.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | import java.util.UUID;
4 |
5 | import org.junit.jupiter.api.Test;
6 | import org.junit.platform.runner.JUnitPlatform;
7 | import org.junit.runner.RunWith;
8 |
9 | import com.datastax.oss.driver.api.core.CqlSession;
10 | import com.datastax.oss.driver.api.core.cql.SimpleStatement;
11 |
12 | @RunWith(JUnitPlatform.class)
13 | public class Ex6e_Remove_A_Todo implements DBConnection {
14 |
15 | @Test
16 | public void should_remove_todos() {
17 | System.out.println("[should_remove_todos] ========================================");
18 | System.out.println("[should_remove_todos] Start Exercise");
19 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
20 | deleteTask(cqlSession, "john", UUID.fromString("11111111-5cff-11ec-be16-1fedb0dfd057"));
21 | TestUtils.showTasks(cqlSession, "john");
22 | }
23 | System.out.println("[should_remove_todos] [OK]");
24 | System.out.println("[should_remove_todos] ========================================\n");
25 | }
26 |
27 | private void deleteTask(CqlSession cqlSession, String user, UUID taskId) {
28 | cqlSession.execute(SimpleStatement.builder(""
29 | + "DELETE FROM todoitems "
30 | + "WHERE user_id=? "
31 | + "AND item_id=?")
32 | .addPositionalValue(user)
33 | .addPositionalValue(taskId)
34 | .build());
35 | }
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/java/com/datastax/workshop/Ex6f_Remove_All_Todos.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.junit.platform.runner.JUnitPlatform;
5 | import org.junit.runner.RunWith;
6 |
7 | import com.datastax.oss.driver.api.core.CqlSession;
8 |
9 | @RunWith(JUnitPlatform.class)
10 | public class Ex6f_Remove_All_Todos implements DBConnection {
11 |
12 | @Test
13 | public void should_remote_all_todos() {
14 | System.out.println("[should_remove_all_todos] ========================================");
15 | System.out.println("[should_remove_all_todos] Start Exercise");
16 | try (CqlSession cqlSession = TestUtils.createCqlSession()) {
17 | cqlSession.execute("TRUNCATE TABLE todoitems;");
18 | TestUtils.showTasks(cqlSession, "john");
19 | }
20 | System.out.println("[should_remove_all_todos] [OK]");
21 | System.out.println("[should_remove_all_todos] ========================================\n");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/java/com/datastax/workshop/TestUtils.java:
--------------------------------------------------------------------------------
1 | package com.datastax.workshop;
2 |
3 | import static com.datastax.oss.driver.api.core.type.DataTypes.BOOLEAN;
4 | import static com.datastax.oss.driver.api.core.type.DataTypes.TEXT;
5 | import static com.datastax.oss.driver.api.core.type.DataTypes.TIMEUUID;
6 | import static com.datastax.oss.driver.api.querybuilder.SchemaBuilder.createTable;
7 |
8 | import java.nio.file.Paths;
9 |
10 | import com.datastax.oss.driver.api.core.CqlSession;
11 | import com.datastax.oss.driver.api.core.cql.SimpleStatement;
12 | import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder;
13 |
14 | public class TestUtils {
15 |
16 | public static final String TABLE_TODOITEMS = "todoitems";
17 | public static final String TODO_USER_ID = "user_id";
18 | public static final String TODO_ITEM_ID = "item_id";
19 | public static final String TODO_TITLE = "title";
20 | public static final String TODO_COMPLETED = "completed";
21 | public static final String TODO_OFFSET = "offset";
22 |
23 | public static CqlSession createCqlSession() {
24 | return CqlSession
25 | .builder()
26 | .withCloudSecureConnectBundle(Paths.get(DBConnection.SECURE_CONNECT_BUNDLE))
27 | .withAuthCredentials(DBConnection.USERNAME, DBConnection.PASSWORD)
28 | .withKeyspace(DBConnection.KEYSPACE)
29 | .build();
30 | }
31 |
32 | /**
33 | * CREATE TABLE todoitems IF NOT EXISTS (
34 | * user_id text,
35 | * item_id timeuuid,
36 | * completed boolean,
37 | * title text,
38 | * PRIMARY KEY ((user_id), item_id)
39 | * ) WITH CLUSTERING ORDER BY (item_id ASC);
40 | */
41 | public static void createTableTodoItem(CqlSession cqlSession) {
42 | cqlSession.execute(
43 | createTable(TABLE_TODOITEMS).ifNotExists()
44 | .withPartitionKey(TODO_USER_ID, TEXT)
45 | .withClusteringColumn(TODO_ITEM_ID, TIMEUUID)
46 | .withColumn(TODO_COMPLETED, BOOLEAN)
47 | .withColumn(TODO_TITLE, TEXT)
48 | .withClusteringOrder(TODO_ITEM_ID, ClusteringOrder.ASC)
49 | .build());
50 | }
51 |
52 |
53 | public static void showTasks(CqlSession cqlSession, String user) {
54 | cqlSession.execute(SimpleStatement
55 | .builder("SELECT item_id, completed, title FROM todoitems WHERE user_id=?")
56 | .addPositionalValue(user).build())
57 | .forEach(row -> {
58 | System.out.println("+" + row.getUuid("item_id") + ": " +
59 | row.getBoolean("completed") + ":" +
60 | row.getString("title"));
61 | });
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/week3-app-development/java/src/test/resources/logback-test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} %magenta(%-5level) %cyan(%-10logger) : %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/Ex06_Connect_to_Astra.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | const result = await client.execute("SELECT * FROM system.local");
9 | result.rows.forEach((row) => {
10 | console.log(
11 | "Your are now connected to Astra '%s' at '%s'",
12 | row.cluster_name,
13 | row.data_center
14 | );
15 | });
16 | console.log("SUCCESS");
17 | } catch (e) {
18 | console.log(e);
19 | }
20 | console.log("========================================");
21 | process.exit();
22 | })();
23 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/Ex6a_Create_Table.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | await client.execute(`
9 | CREATE TABLE IF NOT EXISTS todoitems (
10 | user_id TEXT,
11 | item_id TIMEUUID,
12 | title TEXT,
13 | completed BOOLEAN,
14 | PRIMARY KEY ((user_id), item_id)
15 | ) WITH CLUSTERING ORDER BY (item_id ASC);`);
16 | console.log("SUCCESS");
17 | } catch (e) {
18 | console.log(e);
19 | }
20 | console.log("========================================");
21 | process.exit();
22 | })();
23 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/Ex6b_Insert_Todos.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | await client.execute(
9 | "INSERT INTO todoitems (user_id, item_id, completed, title) VALUES ( 'john', 11111111-5cff-11ec-be16-1fedb0dfd057, true, 'Walk the dog');"
10 | );
11 | await client.execute(
12 | "INSERT INTO todoitems (user_id, item_id, completed, title) VALUES ( 'john', 22222222-5cff-11ec-be16-1fedb0dfd057, false, 'Have lunch tomorrow');"
13 | );
14 | await client.execute(
15 | "INSERT INTO todoitems (user_id, item_id, completed, title) VALUES ( 'mary', 33333333-5cff-11ec-be16-1fedb0dfd057, true, 'Attend the workshop');"
16 | );
17 | console.log("SUCCESS");
18 | } catch (e) {
19 | console.log(e);
20 | }
21 | console.log("========================================");
22 | process.exit();
23 | })();
24 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/Ex6c_Get_All_Todos.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | const result = await client.execute(
9 | "SELECT * FROM todoitems WHERE user_id = 'john';"
10 | );
11 | result.rows.forEach((row) => {
12 | console.log(row);
13 | });
14 | console.log("SUCCESS");
15 | } catch (e) {
16 | console.log(e);
17 | }
18 | console.log("========================================");
19 | process.exit();
20 | })();
21 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/Ex6d_Update_A_Todo.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | await client.execute(
9 | "UPDATE todoitems SET completed = true WHERE user_id = 'john' AND item_id = 22222222-5cff-11ec-be16-1fedb0dfd057;"
10 | );
11 | const result = await client.execute(
12 | "SELECT toTimestamp(item_id), completed, title FROM todoitems WHERE user_id = 'john';"
13 | );
14 | result.rows.forEach((row) => {
15 | console.log(row);
16 | });
17 | console.log("SUCCESS");
18 | } catch (e) {
19 | console.log(e);
20 | }
21 | console.log("========================================");
22 | process.exit();
23 | })();
24 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/Ex6e_Remove_A_Todo.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | await client.execute(
9 | "DELETE FROM todoitems WHERE user_id='john' AND item_id=11111111-5cff-11ec-be16-1fedb0dfd057;"
10 | );
11 | const result = await client.execute(
12 | "SELECT toTimestamp(item_id), completed, title FROM todoitems WHERE user_id = 'john';"
13 | );
14 | result.rows.forEach((row) => {
15 | console.log(row);
16 | });
17 | console.log("SUCCESS");
18 | } catch (e) {
19 | console.log(e);
20 | }
21 | console.log("========================================");
22 | process.exit();
23 | })();
24 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/Ex6f_Remove_All_Todos.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | await client.execute("TRUNCATE TABLE todoitems;");
9 | console.log("SUCCESS");
10 | } catch (e) {
11 | console.log(e);
12 | }
13 | console.log("========================================");
14 | process.exit();
15 | })();
16 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/README.MD:
--------------------------------------------------------------------------------
1 | # 🎓🔥 NodeJS - Back End App Dev with Cassandra 🔥🎓
2 |
3 | 
4 |
5 | ## NodeJS - Back End App Dev with Cassandra
6 |
7 | 
8 |
9 | ## Table of contents
10 |
11 | We will be walking through code that establishes a connection to the Astra database and does CRUD (Create, Read, Update, Delete commands).
12 |
13 | - 6.[Connect to Astra](#-step-6-run-unit-test-ex06_connect_to_astrajs)
14 | - 6a. [Create the todoitems Table](#-step-6a-run-unit-test-ex6a_create_tablejs)
15 | - 6b. [Insert values](#-step-6b-run-unit-test-ex6b_insert_todosjs)
16 | - 6c. [Retrieve all rows](#-step-6c-run-unit-test-ex6c_get_all_todosjs)
17 | - 6d. [Update a todo](#-step-6d-run-unit-test-ex6d_update_a_todojs)
18 | - 6e. [Remove a todo](#-step-6e-run-unit-test-ex6e_remove_a_todojs)
19 | - 6f. [Remove all todos](#-step-6f-run-unit-test-ex6f_remove_all_todosjs)
20 |
21 |
22 | Make sure you're in the right sub-directory (`javascript`) by issuing the following command in the GitPod terminal window.
23 |
24 | ```bash
25 | cd /workspace/bootcamp-fullstack-apps-with-cassandra/week3-app-development/javascript
26 | ```
27 |
28 | Verify again you're in the `javascript` sub-directory using the following command
29 |
30 | ```bash
31 | pwd
32 | ```
33 | **👁️ Expected output**
34 |
35 | ```
36 | /workspace/bootcamp-fullstack-apps-with-cassandra/week3-app-development/javascript
37 | ```
38 |
39 | #### ✅ Step 6a. Run unit test `Ex06_Connect_to_Astra.js`**
40 |
41 | From the GitPod terminal window issue the following command
42 |
43 | ```bash
44 | open connection.js
45 | ```
46 |
47 | and notice the following lines have been updated with the appropriate values.
48 |
49 |
50 | ```javascript
51 | // This is the "Client Id" value you obtained earlier
52 | const USERNAME = "FXXXXXXXXXXl";
53 | // This is the "Client Secret" value you obtained earlier
54 | const PASSWORD = "FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeOE.kio_.L981NQ.xq5HqXDB7s_FIJC.ssbLgbdz+G1IC0BCwIA_ZrwPrQNJWUiv26uZf2f4wo";
55 | ```
56 |
57 | You can optionally issue the following command or notice the changes in the Gitpod explorer window. Hit space bar to proceed through the changes or hit or `q` to exit the command.
58 |
59 |
60 | ```bash
61 | git diff connection.js
62 | ```
63 |
64 | You are ready and can now test the connection to Astra with the following command
65 |
66 | ```bash
67 | node Ex07a_Connect_to_Astra.js
68 | ```
69 | **👁️ Expected output**
70 |
71 | ```
72 | ========================================
73 | Start exercise
74 | ========================================
75 | Your are now connected to Astra 'cndb' at 'us-east1'
76 | SUCCESS
77 | ```
78 | Now that we're successfully able to establish the connection, take a moment to walk through how the connection has been established by opening the source code using the following command
79 |
80 | ```
81 | gp open Ex06_Connect_to_Astra.js
82 | ```
83 |
84 | #### ✅ Step 6a. Run unit test `Ex6a_Create_Table.js`
85 |
86 | Let's create the table.
87 |
88 | Take a moment to review the code with the following command
89 |
90 | ```bash
91 | gp open Ex6a_Create_Table.js
92 | ```
93 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
94 |
95 |
96 | ```bash
97 | node Ex6a_Create_Table.js
98 | ```
99 |
100 | **6a. Test output**
101 |
102 | ```bash
103 | ========================================
104 | Start exercise
105 | SUCCESS
106 | ========================================
107 | ```
108 |
109 | **6a. CQL Console**
110 |
111 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been created.
112 |
113 | ```cql
114 | use todos;
115 | DESCRIBE TABLE todoitems;
116 | ```
117 |
118 | **6a. CQL output**
119 |
120 | **👁️ Expected output**
121 |
122 | ```bash
123 | CREATE TABLE todos.todoitems (
124 | user_id text,
125 | item_id timeuuid,
126 | completed boolean,
127 | title text,
128 | PRIMARY KEY (user_id, item_id)
129 | ) WITH CLUSTERING ORDER BY (item_id ASC)
130 | AND additional_write_policy = '99PERCENTILE'
131 | AND bloom_filter_fp_chance = 0.01
132 | AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
133 | AND comment = ''
134 | AND compaction = {'class': 'org.apache.cassandra.db.compaction.UnifiedCompactionStrategy'}
135 | AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
136 | AND crc_check_chance = 1.0
137 | AND default_time_to_live = 0
138 | AND gc_grace_seconds = 864000
139 | AND max_index_interval = 2048
140 | AND memtable_flush_period_in_ms = 0
141 | AND min_index_interval = 128
142 | AND read_repair = 'BLOCKING'
143 | AND speculative_retry = '99PERCENTILE';
144 | ```
145 |
146 | #### ✅ Step 6b. Run unit test `Ex6b_Insert_Todos.js`
147 |
148 | Let's insert some items.
149 |
150 | Take a moment to review the code with the following command
151 |
152 | ```bash
153 | gp open Ex6b_Insert_Todos.js
154 | ```
155 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
156 |
157 | ```bash
158 | node Ex6b_Insert_Todos.js
159 | ```
160 |
161 | **6b. Test output**
162 |
163 | **👁️ Expected output**
164 |
165 | ```bash
166 | ========================================
167 | Start exercise
168 | SUCCESS
169 | ========================================
170 | ```
171 |
172 | **6b. CQL Console**
173 |
174 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been created.
175 |
176 | ```cql
177 | select * from todoitems;
178 | ```
179 |
180 | **6b. CQL Output**
181 |
182 | **👁️ Expected output**
183 |
184 | ```cql
185 |
186 | user_id | item_id | completed | title
187 | ---------+--------------------------------------+-----------+---------------------
188 | mary | 33333333-5cff-11ec-be16-1fedb0dfd057 | True | Attend the workshop
189 | john | 11111111-5cff-11ec-be16-1fedb0dfd057 | True | Walk the dog
190 | john | 22222222-5cff-11ec-be16-1fedb0dfd057 | False | Have lunch tomorrow
191 |
192 | (3 rows)
193 |
194 | ```
195 |
196 | #### ✅ Step 6c. Run unit test `Ex6c_Get_All_Todos.js`
197 |
198 | Let's get all the todos associated with an user.
199 |
200 | Take a moment to review the code with the following command
201 |
202 | ```bash
203 | gp open Ex6c_Get_All_Todos.js
204 | ```
205 |
206 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
207 |
208 | ```bash
209 | node Ex6c_Get_All_Todos.js
210 | ```
211 |
212 | **6c. Test output**
213 |
214 | **👁️ Expected output**
215 |
216 | ```bash
217 | ========================================
218 | Start exercise
219 | Row {
220 | user_id: 'john',
221 | item_id: TimeUuid {
222 | buffer:
223 | },
224 | completed: false,
225 | title: 'Have lunch tomorrow'
226 | }
227 | SUCCESS
228 | ========================================
229 | ```
230 |
231 | You can verify via the CQL shell or via the console as well as you did in previous step(s).
232 |
233 | #### ✅ Step 6d. Run unit test `Ex6d_Update_A_Todo.js`
234 |
235 | Let's update an item.
236 |
237 | Take a moment to review the code with the following command
238 |
239 | ```bash
240 | gp open Ex6d_Update_A_Todo.js
241 | ```
242 |
243 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
244 |
245 | ```bash
246 | node Ex6d_Update_A_Todo.js
247 | ```
248 |
249 | **6d. Test output**
250 |
251 | **👁️ Expected output**
252 |
253 | ```bash
254 | ========================================
255 | Start exercise
256 | Row {
257 | 'system.totimestamp(item_id)': 2021-12-14T16:59:00.072Z,
258 | completed: true,
259 | title: 'Have lunch tomorrow'
260 | }
261 | SUCCESS
262 | ========================================
263 | ```
264 |
265 | **6d. CQL Console**
266 |
267 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been created.
268 |
269 | ```cql
270 | select * from todoitems;
271 | ```
272 |
273 | **6d. CQL Output**
274 |
275 | **👁️ Expected output**
276 |
277 | ```cql
278 |
279 | user_id | item_id | completed | title
280 | ---------+--------------------------------------+-----------+---------------------
281 | mary | 33333333-5cff-11ec-be16-1fedb0dfd057 | True | Attend the workshop
282 | john | 11111111-5cff-11ec-be16-1fedb0dfd057 | True | Walk the dog
283 | john | 22222222-5cff-11ec-be16-1fedb0dfd057 | True | Have lunch tomorrow
284 |
285 | (3 rows)
286 | ```
287 |
288 | #### ✅ Step 6e. Run unit test `Ex6e_Remove_A_Todo.js`
289 |
290 | Let's remove an item.
291 |
292 | Take a moment to review the code with the following command
293 |
294 | ```bash
295 | gp open Ex6e_Remove_A_Todo.js
296 | ```
297 |
298 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
299 |
300 | ```bash
301 | node Ex6e_Remove_A_Todo.js
302 | ```
303 |
304 | **6e. Test output**
305 |
306 | ```bash
307 | ========================================
308 | Start exercise
309 | Row {
310 | 'system.totimestamp(item_id)': 2021-12-14T16:59:00.072Z,
311 | completed: true,
312 | title: 'Have lunch tomorrow'
313 | }
314 | SUCCESS
315 | ========================================
316 | ```
317 |
318 | **6e. CQL Console**
319 |
320 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been removed.
321 |
322 | ```cql
323 | select * from todoitems;
324 | ```
325 |
326 | **6e. CQL Output**
327 |
328 | **👁️ Expected output**
329 |
330 | ```cql
331 | user_id | item_id | completed | title
332 | ---------+--------------------------------------+-----------+---------------------
333 | mary | 33333333-5cff-11ec-be16-1fedb0dfd057 | True | Attend the workshop
334 | john | 22222222-5cff-11ec-be16-1fedb0dfd057 | True | Have lunch tomorrow
335 |
336 | (2 rows)
337 | ```
338 |
339 | #### ✅ Step 6f. Run unit test `Ex6f_Remove_All_Todos.js`
340 |
341 | Finally, let's remove all todos associated with an user.
342 |
343 | Take a moment to review the code with the following command
344 |
345 | ```bash
346 | gp open Ex6f_Remove_All_Todos.js
347 | ```
348 |
349 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
350 |
351 | ```bash
352 | node Ex6f_Remove_All_Todos.js
353 | ```
354 |
355 | **6f. Test output**
356 |
357 | **👁️ Expected output**
358 |
359 | ```bash
360 | ========================================
361 | Start exercise
362 | SUCCESS
363 | ========================================
364 | ```
365 |
366 | **6f. CQL Console**
367 |
368 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been created.
369 |
370 | **👁️ Expected output**
371 |
372 | ```cql
373 | select * from todoitems;
374 | ```
375 |
376 | **6f. CQL Output**
377 |
378 | ```cql
379 | user_id | item_id | completed | title
380 | ---------+---------+-----------+-------
381 |
382 | (0 rows)
383 | ```
384 |
385 |
386 | **Cleanup**
387 |
388 | **Caution: You will lose all the data** if you run the following command in the CQL Console
389 |
390 | ```cql
391 | DROP TABLE IF EXISTS todos.todoitems;
392 | ```
393 |
394 | [🏠 Go back](../README.MD)
--------------------------------------------------------------------------------
/week3-app-development/javascript/connection.js:
--------------------------------------------------------------------------------
1 | // WARNING: THIS FILE IS GOING TO BE OVERWRITTEN
2 | const cassandra = require("cassandra-driver");
3 |
4 | // This is the Zip file you downloaded
5 | const SECURE_CONNECT_BUNDLE =
6 | "/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip";
7 | // This is the "Client Id" value you obtained earlier
8 | const USERNAME = "";
9 | // This is the "Client Secret" value you obtained earlier
10 | const PASSWORD = "";
11 | // This is the keyspace name
12 | const KEYSPACE = "todos";
13 |
14 | const client = new cassandra.Client({
15 | cloud: { secureConnectBundle: SECURE_CONNECT_BUNDLE },
16 | keyspace: KEYSPACE,
17 | credentials: { username: USERNAME, password: PASSWORD },
18 | });
19 |
20 | process.on("exit", () => client.shutdown());
21 |
22 | module.exports = {
23 | client,
24 | };
25 |
--------------------------------------------------------------------------------
/week3-app-development/javascript/connection.js.init:
--------------------------------------------------------------------------------
1 | // THIS FILE WILL BE OVERWRITTEN. DO NOT MAKE ANY CHANGES
2 | const cassandra = require("cassandra-driver");
3 |
4 | // This is the Zip file you downloaded
5 | const SECURE_CONNECT_BUNDLE =
6 | "/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip";
7 | // This is the "Client Id" value you obtained earlier
8 | const USERNAME = "$ASTRA_USERNAME";
9 | // This is the "Client Secret" value you obtained earlier
10 | const PASSWORD = "$ASTRA_PASSWORD";
11 | // This is the keyspace name
12 | const KEYSPACE = "todos";
13 |
14 | const client = new cassandra.Client({
15 | cloud: { secureConnectBundle: SECURE_CONNECT_BUNDLE },
16 | keyspace: KEYSPACE,
17 | credentials: { username: USERNAME, password: PASSWORD },
18 | });
19 |
20 | process.on("exit", () => client.shutdown());
21 |
22 | module.exports = {
23 | client,
24 | };
25 |
--------------------------------------------------------------------------------
/week3-app-development/plugastracreds:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ ! -f .env ]; then
4 | echo "File .env needs to exist."
5 | exit -1
6 | fi
7 |
8 | source .env
9 |
10 | if [ ! "$ASTRA_USERNAME" ]; then
11 | echo "env variable ASTRA_USERNAME needs to be set"
12 | exit -1
13 | fi
14 |
15 | if [ ! "$ASTRA_PASSWORD" ]; then
16 | echo "env variable ASTRA_PASSWORD needs to be set"
17 | exit -1
18 | fi
19 |
20 | if [ ! -f /workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip ]; then
21 | echo "Secure connect bundle to connect to Astra does not exist."
22 | exit -1
23 | fi
24 |
25 | cat ./java/src/main/java/com/datastax/workshop/DBConnection.java.init | \
26 | sed "s/\$ASTRA_USERNAME/$ASTRA_USERNAME/" | \
27 | sed "s/\$ASTRA_PASSWORD/$ASTRA_PASSWORD/" > \
28 | ./java/src/main/java/com/datastax/workshop/DBConnection.java
29 |
30 | cat ./javascript/connection.js.init | \
31 | sed "s/\$ASTRA_USERNAME/$ASTRA_USERNAME/" | \
32 | sed "s/\$ASTRA_PASSWORD/$ASTRA_PASSWORD/" > \
33 | ./javascript/connection.js
34 |
35 | cat ./python/connection.py.init | \
36 | sed "s/\$ASTRA_USERNAME/$ASTRA_USERNAME/" | \
37 | sed "s/\$ASTRA_PASSWORD/$ASTRA_PASSWORD/" > \
38 | ./python/connection.py
39 |
40 | echo "Astra credentials plugged into all language environments. Please verify!"
41 |
42 |
43 | if [ ! -f /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit ]; then
44 | cp ~/.zshrc /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit
45 | echo "/workspace/bootcamp-fullstack-apps-with-cassandra/cqlsh-astra/bin/cqlsh \\
46 | --secure-connect-bundle=/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip \\
47 | --color \\
48 | -u $ASTRA_USERNAME \\
49 | -p $ASTRA_PASSWORD" >> /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit
50 | cp /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit ~/.zshrc
51 | else
52 | cp /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit ~/.zshrc
53 | fi
54 |
55 | touch /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit
56 |
--------------------------------------------------------------------------------
/week3-app-development/python/Ex06_Connect_to_Astra.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from connection import session
3 |
4 | print('========================================')
5 | print('Start exercise')
6 | try:
7 | output = session.execute("SELECT * FROM system.local")
8 | for row in output:
9 | print('You are now connected to cluster %s at %s' %
10 | (row.cluster_name, row.data_center))
11 | except Exception as e:
12 | print(e)
13 | print('Failure')
14 | else:
15 | print('Success')
16 | print('========================================')
17 |
--------------------------------------------------------------------------------
/week3-app-development/python/Ex6a_Create_Table.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from connection import session
3 |
4 | print('========================================')
5 | print('Start exercise')
6 | try:
7 | session.execute("""CREATE TABLE IF NOT EXISTS todoitems (
8 | user_id TEXT,
9 | item_id TIMEUUID,
10 | title TEXT,
11 | completed BOOLEAN,
12 | PRIMARY KEY ((user_id), item_id)
13 | ) WITH CLUSTERING ORDER BY (item_id ASC);
14 | """)
15 | except Exception as e:
16 | print(e)
17 | print('Failure')
18 | else:
19 | print('Success')
20 | print('========================================')
21 |
--------------------------------------------------------------------------------
/week3-app-development/python/Ex6b_Insert_Todos.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import uuid
3 | from connection import session
4 |
5 | print('========================================')
6 | print('Start exercise')
7 | try:
8 | session.execute(
9 | "INSERT INTO todoitems (user_id, item_id, completed, title) VALUES ( 'john', 11111111-5cff-11ec-be16-1fedb0dfd057, true, 'Walk the dog');")
10 | session.execute(
11 | "INSERT INTO todoitems (user_id, item_id, completed, title) VALUES ( 'john', 22222222-5cff-11ec-be16-1fedb0dfd057, false, 'Have lunch tomorrow');")
12 | session.execute(
13 | "INSERT INTO todoitems (user_id, item_id, completed, title) VALUES ( 'mary', 33333333-5cff-11ec-be16-1fedb0dfd057, true, 'Attend the workshop');")
14 | except Exception as e:
15 | print(e)
16 | print('Failure')
17 | else:
18 | print('Success')
19 | print('========================================')
20 |
--------------------------------------------------------------------------------
/week3-app-development/python/Ex6c_Get_All_Todos.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from connection import session
3 |
4 | print('========================================')
5 | print('Start exercise')
6 | try:
7 | output = session.execute("SELECT * FROM todoitems WHERE user_id = 'john';")
8 | for row in output:
9 | print(str(row))
10 | except Exception as e:
11 | print(e)
12 | print('Failure')
13 | else:
14 | print('Success')
15 | print('========================================')
16 |
--------------------------------------------------------------------------------
/week3-app-development/python/Ex6d_Update_A_Todo.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from connection import session
3 |
4 | print('========================================')
5 | print('Start exercise')
6 | try:
7 | session.execute(
8 | "UPDATE todoitems SET completed = true WHERE user_id = 'john' AND item_id = 22222222-5cff-11ec-be16-1fedb0dfd057;")
9 | output = session.execute(
10 | "SELECT toTimestamp(item_id), completed, title FROM todoitems WHERE user_id = 'john';")
11 | for row in output:
12 | print(row)
13 | except Exception as e:
14 | print(e)
15 | print('Failure')
16 | else:
17 | print('Success')
18 | print('========================================')
19 |
--------------------------------------------------------------------------------
/week3-app-development/python/Ex6e_Remove_A_Todo.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from connection import session
3 |
4 | print('========================================')
5 | print('Start exercise')
6 | try:
7 | session.execute(
8 | "DELETE FROM todoitems WHERE user_id='john' AND item_id=11111111-5cff-11ec-be16-1fedb0dfd057;")
9 | output = session.execute(
10 | "SELECT toTimestamp(item_id), completed, title FROM todoitems WHERE user_id = 'john';")
11 | for row in output:
12 | print(row)
13 | except Exception as e:
14 | print(e)
15 | print('Failure')
16 | else:
17 | print('Success')
18 | print('========================================')
19 |
--------------------------------------------------------------------------------
/week3-app-development/python/Ex6f_Remove_All_Todos.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from connection import session
3 |
4 | print('========================================')
5 | print('Start exercise')
6 | try:
7 | session.execute("TRUNCATE TABLE todoitems;")
8 | except Exception as e:
9 | print(e)
10 | print('Failure')
11 | else:
12 | print('Success')
13 | print('========================================')
14 |
--------------------------------------------------------------------------------
/week3-app-development/python/README.MD:
--------------------------------------------------------------------------------
1 | # 🎓🔥 Python - Back End App Dev with Cassandra 🔥🎓
2 |
3 | 
4 |
5 | ## Python - Back End App Dev with Cassandra
6 |
7 | 
8 |
9 | ## Table of contents
10 |
11 | We will be walking through code that establishes a connection to the Astra database and does CRUD (Create, Read, Update, Delete commands).
12 |
13 | - 6.[Connect to Astra](#-step-6-run-unit-test-ex06_connect_to_astrapy)
14 | - 6a. [Create the todoitems Table](#-step-6a-run-unit-test-ex6a_create_tablepy)
15 | - 6b. [Insert values](#-step-6b-run-unit-test-ex6b_insert_todospy)
16 | - 6c. [Retrieve all rows](#-step-6c-run-unit-test-ex6c_get_all_todospy)
17 | - 6d. [Update a todo](#-step-6d-run-unit-test-ex6d_update_a_todopy)
18 | - 6e. [Remove a todo](#-step-6e-run-unit-test-ex6e_remove_a_todopy)
19 | - 6f. [Remove all todos](#-step-6f-run-unit-test-ex6f_remove_all_todospy)
20 |
21 |
22 | Make sure you're in the right sub-directory (`python`) by issuing the following command in the GitPod terminal window.
23 |
24 | ```bash
25 | cd /workspace/bootcamp-fullstack-apps-with-cassandra/week3-app-development/python
26 | ```
27 |
28 | Verify again you're in the `python` sub-directory using the following command
29 |
30 | ```bash
31 | pwd
32 | ```
33 | **👁️ Expected output**
34 |
35 | ```
36 | /workspace/bootcamp-fullstack-apps-with-cassandra/week3-app-development/python
37 | ```
38 |
39 | #### ✅ Step 6a. Run unit test `Ex06_Connect_to_Astra.py`
40 |
41 | From the GitPod terminal window issue the following command
42 |
43 | ```bash
44 | open connection.py
45 | ```
46 |
47 | and notice the following lines have been updated with the appropriate values.
48 |
49 |
50 | ```javascript
51 | // This is the "Client Id" value you obtained earlier
52 | const USERNAME = "FXXXXXXXXXXl";
53 | // This is the "Client Secret" value you obtained earlier
54 | const PASSWORD = "FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeOE.kio_.L981NQ.xq5HqXDB7s_FIJC.ssbLgbdz+G1IC0BCwIA_ZrwPrQNJWUiv26uZf2f4wo";
55 | ```
56 |
57 | You can optionally issue the following command or notice the changes in the Gitpod explorer window. Hit space bar to proceed through the changes or hit or `q` to exit the command.
58 |
59 |
60 | ```bash
61 | git diff connection.py
62 | ```
63 |
64 | You are ready and can now test the connection to Astra with the following command
65 |
66 | ```bash
67 | python Ex06_Connect_to_Astra.py
68 | ```
69 | **👁️ Expected output**
70 |
71 | ```
72 | ========================================
73 | Start exercise
74 | You are now connected to cluster cndb at us-east1
75 | Success
76 | ========================================
77 | ```
78 |
79 | Now that we're successfully able to establish the connection, take a moment to walk through how the connection has been established by opening the source code using the following command
80 |
81 | ```
82 | gp open Ex06_Connect_to_Astra.py
83 | ```
84 |
85 | #### ✅ Step 6a. Run unit test `Ex6a_Create_Table.py`
86 |
87 | Let's create the table.
88 |
89 | Take a moment to review the code with the following command
90 |
91 | ```bash
92 | gp open Ex6a_Create_Table.py
93 | ```
94 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
95 |
96 |
97 | ```bash
98 | python Ex6a_Create_Table.py
99 | ```
100 |
101 | **6a. Test output**
102 |
103 | ```bash
104 | ========================================
105 | Start exercise
106 | Success
107 | ========================================
108 | ```
109 |
110 | **6a. CQL Console**
111 |
112 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been created.
113 |
114 | ```cql
115 | use todos;
116 | DESCRIBE TABLE todoitems;
117 | ```
118 |
119 | **6a. CQL output**
120 |
121 | **👁️ Expected output**
122 |
123 | ```bash
124 | CREATE TABLE todos.todoitems (
125 | user_id text,
126 | item_id timeuuid,
127 | completed boolean,
128 | title text,
129 | PRIMARY KEY (user_id, item_id)
130 | ) WITH CLUSTERING ORDER BY (item_id ASC)
131 | AND additional_write_policy = '99PERCENTILE'
132 | AND bloom_filter_fp_chance = 0.01
133 | AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
134 | AND comment = ''
135 | AND compaction = {'class': 'org.apache.cassandra.db.compaction.UnifiedCompactionStrategy'}
136 | AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
137 | AND crc_check_chance = 1.0
138 | AND default_time_to_live = 0
139 | AND gc_grace_seconds = 864000
140 | AND max_index_interval = 2048
141 | AND memtable_flush_period_in_ms = 0
142 | AND min_index_interval = 128
143 | AND read_repair = 'BLOCKING'
144 | AND speculative_retry = '99PERCENTILE';
145 | ```
146 |
147 | #### ✅ Step 6b. Run unit test `Ex6b_Insert_Todos.py`
148 |
149 | Let's insert some items.
150 |
151 | Take a moment to review the code with the following command
152 |
153 | ```bash
154 | gp open Ex6b_Insert_Todos.py
155 | ```
156 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
157 |
158 | ```bash
159 | python Ex6b_Insert_Todos.py
160 | ```
161 |
162 | **6b. Test output**
163 |
164 | **👁️ Expected output**
165 |
166 | ```bash
167 | ========================================
168 | Start exercise
169 | Success
170 | ========================================
171 | ```
172 |
173 | **6b. CQL Console**
174 |
175 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been created.
176 |
177 | ```cql
178 | select * from todoitems;
179 | ```
180 |
181 | **6b. CQL Output**
182 |
183 | **👁️ Expected output**
184 |
185 | ```bash
186 |
187 | user_id | item_id | completed | title
188 | ---------+--------------------------------------+-----------+---------------------
189 | mary | 33333333-5cff-11ec-be16-1fedb0dfd057 | True | Attend the workshop
190 | john | 11111111-5cff-11ec-be16-1fedb0dfd057 | True | Walk the dog
191 | john | 22222222-5cff-11ec-be16-1fedb0dfd057 | False | Have lunch tomorrow
192 |
193 | (3 rows)
194 |
195 | ```
196 |
197 | #### ✅ Step 6c. Run unit test `Ex6c_Get_All_Todos.py`
198 |
199 | Let's get all the todos associated with an user.
200 |
201 | Take a moment to review the code with the following command
202 |
203 | ```bash
204 | gp open Ex6c_Get_All_Todos.py
205 | ```
206 |
207 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
208 |
209 | ```bash
210 | python Ex6c_Get_All_Todos.py
211 | ```
212 |
213 | **6c. Test output**
214 |
215 | **👁️ Expected output**
216 |
217 | ```bash
218 | ========================================
219 | Start exercise
220 | Row(user_id='john', item_id=UUID('11111111-5cff-11ec-be16-1fedb0dfd057'), completed=True, title='Walk the dog')
221 | Row(user_id='john', item_id=UUID('22222222-5cff-11ec-be16-1fedb0dfd057'), completed=False, title='Have lunch tomorrow')
222 | Success
223 | ========================================
224 | ```
225 |
226 | You can verify via the CQL shell or via the console as well as you did in previous step(s).
227 |
228 | #### ✅ Step 6d. Run unit test `Ex6d_Update_A_Todo.py`
229 |
230 | Let's update an item.
231 |
232 | Take a moment to review the code with the following command
233 |
234 | ```bash
235 | gp open Ex6d_Update_A_Todo.py
236 | ```
237 |
238 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
239 |
240 | ```bash
241 | python Ex6d_Update_A_Todo.py
242 | ```
243 |
244 | **6d. Test output**
245 |
246 | **👁️ Expected output**
247 |
248 | ```bash
249 | ========================================
250 | Start exercise
251 | Row(system_totimestamp_item_id=datetime.datetime(2021, 12, 14, 16, 58, 31, 438000), completed=True, title='Walk the dog')
252 | Row(system_totimestamp_item_id=datetime.datetime(2021, 12, 14, 16, 59, 0, 72000), completed=True, title='Have lunch tomorrow')
253 | Success
254 | ========================================
255 | ```
256 |
257 | **6d. CQL Console**
258 |
259 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been created.
260 |
261 | ```cql
262 | select * from todoitems;
263 | ```
264 |
265 | **6d. CQL Output**
266 |
267 | **👁️ Expected output**
268 |
269 | ```cql
270 |
271 | user_id | item_id | completed | title
272 | ---------+--------------------------------------+-----------+---------------------
273 | mary | 33333333-5cff-11ec-be16-1fedb0dfd057 | True | Attend the workshop
274 | john | 11111111-5cff-11ec-be16-1fedb0dfd057 | True | Walk the dog
275 | john | 22222222-5cff-11ec-be16-1fedb0dfd057 | True | Have lunch tomorrow
276 |
277 | (3 rows)
278 | ```
279 |
280 | #### ✅ Step 6e. Run unit test `Ex6e_Remove_A_Todo.py`
281 |
282 | Let's remove an item.
283 |
284 | Take a moment to review the code with the following command
285 |
286 | ```bash
287 | gp open Ex6e_Remove_A_Todo.py
288 | ```
289 |
290 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
291 |
292 | ```bash
293 | python Ex6e_Remove_A_Todo.py
294 | ```
295 |
296 | **6e. Test output**
297 |
298 | ```bash
299 | ========================================
300 | Start exercise
301 | Row(system_totimestamp_item_id=datetime.datetime(2021, 12, 14, 16, 59, 0, 72000), completed=True, title='Have lunch tomorrow')
302 | Success
303 | ========================================
304 | ```
305 |
306 | **6e. CQL Console**
307 |
308 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been removed.
309 |
310 | ```cql
311 | select * from todoitems;
312 | ```
313 |
314 | **6e. CQL Output**
315 |
316 | **👁️ Expected output**
317 |
318 | ```cql
319 | user_id | item_id | completed | title
320 | ---------+--------------------------------------+-----------+---------------------
321 | mary | 33333333-5cff-11ec-be16-1fedb0dfd057 | True | Attend the workshop
322 | john | 22222222-5cff-11ec-be16-1fedb0dfd057 | True | Have lunch tomorrow
323 |
324 | (2 rows)
325 | ```
326 |
327 | #### ✅ Step 6f. Run unit test `Ex6f_Remove_All_Todos.py`
328 |
329 | Finally, let's remove all todos associated with an user.
330 |
331 | Take a moment to review the code with the following command
332 |
333 | ```bash
334 | gp open Ex6f_Remove_All_Todos.py
335 | ```
336 |
337 | After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
338 |
339 | ```bash
340 | python Ex6f_Remove_All_Todos.py
341 | ```
342 |
343 | **6f. Test output**
344 |
345 | **👁️ Expected output**
346 |
347 | ```bash
348 | ========================================
349 | Start exercise
350 | Success
351 | ========================================
352 | ```
353 |
354 | **6f. CQL Console**
355 |
356 | From either the CQL shell window or the CQL console in the Astra console issue the following command to notice the items that have been created.
357 |
358 | **👁️ Expected output**
359 |
360 | ```cql
361 | select * from todoitems;
362 | ```
363 |
364 | **6f. CQL Output**
365 |
366 | ```cql
367 | user_id | item_id | completed | title
368 | ---------+---------+-----------+-------
369 |
370 | (0 rows)
371 | ```
372 |
373 |
374 | **Cleanup**
375 |
376 | **Caution: You will lose all the data** if you run the following command in the CQL Console
377 |
378 | ```cql
379 | DROP TABLE IF EXISTS todos.todoitems;
380 | ```
381 |
382 | [🏠 Go back](../README.MD)
--------------------------------------------------------------------------------
/week3-app-development/python/connection.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | #WARNING: THIS FILE IS GOING TO BE OVERWRITTEN
3 |
4 | import atexit
5 | from cassandra.cluster import Cluster
6 | from cassandra.auth import PlainTextAuthProvider
7 |
8 | # This is the Zip file you downloaded
9 | SECURE_CONNECT_BUNDLE = '/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip'
10 | # This is the "Client Id" value you obtained earlier
11 | USERNAME = ""
12 | # This is the "Client Secret" value you obtained earlier
13 | PASSWORD = ""
14 | # This is the keyspace name
15 | KEYSPACE = "todos"
16 |
17 |
18 | secure_connect_bundle = SECURE_CONNECT_BUNDLE
19 | path_to_creds = ''
20 | cluster = Cluster(
21 | cloud={
22 | 'secure_connect_bundle': SECURE_CONNECT_BUNDLE
23 | },
24 | auth_provider=PlainTextAuthProvider(USERNAME, PASSWORD)
25 | )
26 | session = cluster.connect(KEYSPACE)
27 |
28 |
29 | @atexit.register
30 | def shutdown_driver():
31 | cluster.shutdown()
32 | session.shutdown()
33 |
--------------------------------------------------------------------------------
/week3-app-development/python/connection.py.init:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # THIS FILE WILL BE OVERWRITTEN. DO NOT MAKE ANY CHANGES HERE
3 |
4 | import atexit
5 | from cassandra.cluster import Cluster
6 | from cassandra.auth import PlainTextAuthProvider
7 |
8 | # This is the Zip file you downloaded
9 | SECURE_CONNECT_BUNDLE = '/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip'
10 | # This is the "Client Id" value you obtained earlier
11 | USERNAME = "$ASTRA_USERNAME"
12 | # This is the "Client Secret" value you obtained earlier
13 | PASSWORD = "$ASTRA_PASSWORD"
14 | # This is the keyspace name
15 | KEYSPACE = "todos"
16 |
17 |
18 | secure_connect_bundle = SECURE_CONNECT_BUNDLE
19 | path_to_creds = ''
20 | cluster = Cluster(
21 | cloud={
22 | 'secure_connect_bundle': SECURE_CONNECT_BUNDLE
23 | },
24 | auth_provider=PlainTextAuthProvider(USERNAME, PASSWORD)
25 | )
26 | session = cluster.connect(KEYSPACE)
27 |
28 |
29 | @atexit.register
30 | def shutdown_driver():
31 | cluster.shutdown()
32 | session.shutdown()
33 |
--------------------------------------------------------------------------------
/week3-app-development/slides/WEEK3 - App Development with Cassandra.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week3-app-development/slides/WEEK3 - App Development with Cassandra.pdf
--------------------------------------------------------------------------------
/week4-api-microservices/.env.sample:
--------------------------------------------------------------------------------
1 | #TODO: REPLACE_ME with Astra Client Id and Secret
2 |
3 | export ASTRA_USERNAME=
4 | export ASTRA_PASSWORD=
--------------------------------------------------------------------------------
/week4-api-microservices/images/Filexplorer0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/Filexplorer0.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/OpenPorts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/OpenPorts.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/Verifytodos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/Verifytodos.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/allow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/allow.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/astra-create-token.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/astra-create-token.gif
--------------------------------------------------------------------------------
/week4-api-microservices/images/astra-token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/astra-token.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/bootcamp_badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/bootcamp_badge.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/dotenv1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/dotenv1.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/dotenv2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/dotenv2.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/dotenv3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/dotenv3.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/dotenv4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/dotenv4.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/dotenv5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/dotenv5.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-01-home-annotated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-01-home-annotated.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-01-home-plain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-01-home-plain.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-02-url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-02-url.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-bootcampappdev-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-bootcampappdev-1.jpg
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-client-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-client-error.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-client-success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-client-success.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-home-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-home-error.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-john-task.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-john-task.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-openport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-openport.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-spec-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-spec-error.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpod-spec-success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpod-spec-success.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/gitpodpreferences1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/gitpodpreferences1.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/public9191.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/public9191.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/resume-db.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/resume-db.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/secureconnectbundle1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/secureconnectbundle1.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/secureconnectbundle2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/secureconnectbundle2.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/secureconnectbundle3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/secureconnectbundle3.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/shells.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/shells.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/splash.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/todobackend-output-client.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/todobackend-output-client.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/todobackend-output-host.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/todobackend-output-host.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/todobackend-runclient.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/todobackend-runclient.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/todobackend-runtest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/todobackend-runtest.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/todobackend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/todobackend.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/todobackend2-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/todobackend2-1.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/todomvc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/todomvc.png
--------------------------------------------------------------------------------
/week4-api-microservices/images/week4_badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/images/week4_badge.png
--------------------------------------------------------------------------------
/week4-api-microservices/java/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.datastaxdev
6 | week4-todo-springboot
7 | 1.0.0-SNAPSHOT
8 |
9 |
10 | org.springframework.boot
11 | spring-boot-starter-parent
12 | 2.6.2
13 |
14 |
15 |
16 |
17 | 11
18 |
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-web
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-data-cassandra
30 |
31 |
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-test
36 | test
37 |
38 |
39 | org.junit.vintage
40 | junit-vintage-engine
41 |
42 |
43 | com.vaadin.external.google
44 | android-json
45 |
46 |
47 |
48 |
49 | org.junit.platform
50 | junit-platform-runner
51 | test
52 |
53 |
54 |
55 |
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-maven-plugin
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/java/com/datastaxdev/TodoApplication.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class TodoApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(TodoApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/java/com/datastaxdev/conf/CassandraDriverConguration.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev.conf;
2 |
3 | import java.io.File;
4 |
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.boot.autoconfigure.cassandra.CqlSessionBuilderCustomizer;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | @Configuration
11 | public class CassandraDriverConguration {
12 |
13 | @Value("${datastax.astra.secure-connect-bundle}")
14 | private File cloudSecureBundle;
15 |
16 | @Bean
17 | public CqlSessionBuilderCustomizer sessionBuilderCustomizer() {
18 | return builder -> builder.withCloudSecureConnectBundle(cloudSecureBundle.toPath());
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/java/com/datastaxdev/todo/Todo.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev.todo;
2 |
3 | import java.util.UUID;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 |
7 | /**
8 | * Class to TODO
9 | *
10 | * @author Cedrick LUNVEN (@clunven)
11 | */
12 | public class Todo {
13 |
14 | private String url;
15 | private UUID uuid;
16 | private String title;
17 | private boolean completed = false;
18 | private Integer order = 0;
19 |
20 | public Todo() {}
21 |
22 | public Todo(String title, Integer order) {
23 | this.uuid = UUID.randomUUID();
24 | this.title = title;
25 | this.order = order;
26 | }
27 |
28 | public Todo(String title, int order, boolean completed) {
29 | this(title, order);
30 | this.completed = completed;
31 | }
32 |
33 | public Todo setUrl(HttpServletRequest req) {
34 | if (url == null) {
35 | String reqUrl = req.getRequestURL().toString();
36 | url = reqUrl.contains("gitpod") ? reqUrl.replaceAll("http", "https") : reqUrl;
37 | url += uuid;
38 | }
39 | return this;
40 | }
41 |
42 | public Todo setUrl(String myUrl) {
43 | if (url == null) {
44 | url = myUrl.contains("gitpod") ? myUrl.replaceAll("http", "https") : myUrl;
45 | }
46 | return this;
47 | }
48 |
49 | /**
50 | * Getter accessor for attribute 'uuid'.
51 | *
52 | * @return
53 | * current value of 'uuid'
54 | */
55 | public UUID getUuid() {
56 | return uuid;
57 | }
58 |
59 | /**
60 | * Setter accessor for attribute 'uuid'.
61 | * @param uuid
62 | * new value for 'uuid '
63 | */
64 | public void setUuid(UUID uuid) {
65 | this.uuid = uuid;
66 | }
67 |
68 | /**
69 | * Getter accessor for attribute 'title'.
70 | *
71 | * @return
72 | * current value of 'title'
73 | */
74 | public String getTitle() {
75 | return title;
76 | }
77 |
78 | /**
79 | * Setter accessor for attribute 'title'.
80 | * @param title
81 | * new value for 'title '
82 | */
83 | public void setTitle(String title) {
84 | this.title = title;
85 | }
86 |
87 | /**
88 | * Getter accessor for attribute 'completed'.
89 | *
90 | * @return
91 | * current value of 'completed'
92 | */
93 | public boolean isCompleted() {
94 | return completed;
95 | }
96 |
97 | /**
98 | * Setter accessor for attribute 'completed'.
99 | * @param completed
100 | * new value for 'completed '
101 | */
102 | public void setCompleted(boolean completed) {
103 | this.completed = completed;
104 | }
105 |
106 | /**
107 | * Getter accessor for attribute 'order'.
108 | *
109 | * @return
110 | * current value of 'order'
111 | */
112 | public Integer getOrder() {
113 | return order;
114 | }
115 |
116 | /**
117 | * Setter accessor for attribute 'order'.
118 | * @param order
119 | * new value for 'order '
120 | */
121 | public void setOrder(Integer order) {
122 | this.order = order;
123 | }
124 |
125 | /**
126 | * Getter accessor for attribute 'url'.
127 | *
128 | * @return
129 | * current value of 'url'
130 | */
131 | public String getUrl() {
132 | return url;
133 | }
134 |
135 | /** {@inheritDoc} */
136 | @Override
137 | public String toString() {
138 | return "Todo [url=" + url + ", uuid=" + uuid + ", title=" + title + ", completed=" + completed + ", order=" + order + "]";
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/java/com/datastaxdev/todo/TodoItem.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev.todo;
2 |
3 | import org.springframework.data.cassandra.core.mapping.Column;
4 | import org.springframework.data.cassandra.core.mapping.PrimaryKey;
5 | import org.springframework.data.cassandra.core.mapping.Table;
6 |
7 | import com.datastax.oss.driver.api.core.uuid.Uuids;
8 |
9 | @Table("todoitems")
10 | public class TodoItem {
11 |
12 | @PrimaryKey
13 | private TodoItemKey key = new TodoItemKey("default", Uuids.timeBased());
14 |
15 | @Column("title")
16 | private String title;
17 |
18 | @Column("completed")
19 | private boolean completed = false;
20 |
21 | @Column("offset")
22 | private Integer offset = 0;
23 |
24 | /**
25 | * Default Constructor.
26 | */
27 | public TodoItem() {}
28 |
29 | /**
30 | * Simple constructor.
31 | *
32 | * @param userid
33 | * user id
34 | * @param title
35 | * title
36 | */
37 | public TodoItem(String userid, String title) {
38 | this.title = title;
39 | this.key.setUserId(userid);
40 | }
41 |
42 | /**
43 | * Getter accessor for attribute 'key'.
44 | *
45 | * @return
46 | * current value of 'key'
47 | */
48 | public TodoItemKey getKey() {
49 | return key;
50 | }
51 |
52 | /**
53 | * Setter accessor for attribute 'key'.
54 | * @param key
55 | * new value for 'key '
56 | */
57 | public void setKey(TodoItemKey key) {
58 | this.key = key;
59 | }
60 |
61 | /**
62 | * Getter accessor for attribute 'title'.
63 | *
64 | * @return
65 | * current value of 'title'
66 | */
67 | public String getTitle() {
68 | return title;
69 | }
70 |
71 | /**
72 | * Setter accessor for attribute 'title'.
73 | * @param title
74 | * new value for 'title '
75 | */
76 | public void setTitle(String title) {
77 | this.title = title;
78 | }
79 |
80 | /**
81 | * Getter accessor for attribute 'completed'.
82 | *
83 | * @return
84 | * current value of 'completed'
85 | */
86 | public boolean isCompleted() {
87 | return completed;
88 | }
89 |
90 | /**
91 | * Setter accessor for attribute 'completed'.
92 | * @param completed
93 | * new value for 'completed '
94 | */
95 | public void setCompleted(boolean completed) {
96 | this.completed = completed;
97 | }
98 |
99 | /**
100 | * Getter accessor for attribute 'offset'.
101 | *
102 | * @return
103 | * current value of 'offset'
104 | */
105 | public Integer getOffset() {
106 | return offset;
107 | }
108 |
109 | /**
110 | * Setter accessor for attribute 'offset'.
111 | * @param offset
112 | * new value for 'offset '
113 | */
114 | public void setOffset(int offset) {
115 | this.offset = offset;
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/java/com/datastaxdev/todo/TodoItemKey.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev.todo;
2 |
3 | import java.util.UUID;
4 |
5 | import org.springframework.data.cassandra.core.cql.Ordering;
6 | import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
7 | import org.springframework.data.cassandra.core.mapping.CassandraType;
8 | import org.springframework.data.cassandra.core.mapping.CassandraType.Name;
9 | import org.springframework.data.cassandra.core.mapping.PrimaryKeyClass;
10 | import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
11 |
12 | @PrimaryKeyClass
13 | public class TodoItemKey {
14 |
15 | @PrimaryKeyColumn(name = "user_id",type = PrimaryKeyType.PARTITIONED, ordinal = 0)
16 | private String userId;
17 |
18 | @PrimaryKeyColumn(name = "item_id", type = PrimaryKeyType.CLUSTERED, ordinal = 1, ordering = Ordering.ASCENDING)
19 | @CassandraType(type = Name.TIMEUUID)
20 | private UUID itemId;
21 |
22 | public TodoItemKey() {}
23 |
24 | public TodoItemKey(String userId, UUID itemId) {
25 | super();
26 | this.userId = userId;
27 | this.itemId = itemId;
28 | }
29 |
30 | /**
31 | * Getter accessor for attribute 'userId'.
32 | *
33 | * @return
34 | * current value of 'userId'
35 | */
36 | public String getUserId() {
37 | return userId;
38 | }
39 |
40 | /**
41 | * Setter accessor for attribute 'userId'.
42 | * @param userId
43 | * new value for 'userId '
44 | */
45 | public void setUserId(String userId) {
46 | this.userId = userId;
47 | }
48 |
49 | /**
50 | * Getter accessor for attribute 'itemId'.
51 | *
52 | * @return
53 | * current value of 'itemId'
54 | */
55 | public UUID getItemId() {
56 | return itemId;
57 | }
58 |
59 | /**
60 | * Setter accessor for attribute 'itemId'.
61 | * @param itemId
62 | * new value for 'itemId '
63 | */
64 | public void setItemId(UUID itemId) {
65 | this.itemId = itemId;
66 | }
67 |
68 |
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/java/com/datastaxdev/todo/TodoItemRepository.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev.todo;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.cassandra.repository.CassandraRepository;
6 | import org.springframework.stereotype.Repository;
7 |
8 | /**
9 | * For Basic operations you can leverage on Interface only repository
10 | */
11 | @Repository
12 | public interface TodoItemRepository extends CassandraRepository {
13 |
14 | /**
15 | * Retrieve all todos for a user as the userId is the partition key.
16 | *
17 | * @param userid
18 | * unique identifier for a user
19 | * @return
20 | */
21 | List findByKeyUserId(String userid);
22 |
23 | /**
24 | * Delete all tasks for a todolist.
25 | *
26 | * @param userid
27 | * current userid.
28 | */
29 | void deleteByKeyUserId(String userid);
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/java/com/datastaxdev/todo/TodoRestController.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev.todo;
2 |
3 | import static org.springframework.web.bind.annotation.RequestMethod.DELETE;
4 | import static org.springframework.web.bind.annotation.RequestMethod.GET;
5 | import static org.springframework.web.bind.annotation.RequestMethod.OPTIONS;
6 | import static org.springframework.web.bind.annotation.RequestMethod.PATCH;
7 | import static org.springframework.web.bind.annotation.RequestMethod.POST;
8 | import static org.springframework.web.bind.annotation.RequestMethod.PUT;
9 |
10 | import java.net.URI;
11 | import java.net.URISyntaxException;
12 | import java.util.Optional;
13 | import java.util.UUID;
14 | import java.util.stream.Stream;
15 |
16 | import javax.servlet.http.HttpServletRequest;
17 |
18 | import org.springframework.http.HttpStatus;
19 | import org.springframework.http.ResponseEntity;
20 | import org.springframework.web.bind.annotation.CrossOrigin;
21 | import org.springframework.web.bind.annotation.DeleteMapping;
22 | import org.springframework.web.bind.annotation.GetMapping;
23 | import org.springframework.web.bind.annotation.PatchMapping;
24 | import org.springframework.web.bind.annotation.PathVariable;
25 | import org.springframework.web.bind.annotation.PostMapping;
26 | import org.springframework.web.bind.annotation.RequestBody;
27 | import org.springframework.web.bind.annotation.RequestMapping;
28 | import org.springframework.web.bind.annotation.RestController;
29 |
30 | @RestController
31 | @CrossOrigin(
32 | methods = {POST, GET, OPTIONS, PUT, DELETE, PATCH},
33 | maxAge = 3600,
34 | allowedHeaders = {"x-requested-with", "origin", "content-type", "accept"},
35 | origins = "*"
36 | )
37 | @RequestMapping("/api/v1")
38 | public class TodoRestController {
39 |
40 | private TodoItemRepository repo;
41 |
42 | public TodoRestController(TodoItemRepository todoRepo) {
43 | this.repo = todoRepo;
44 | }
45 |
46 | @GetMapping("/{user}/todos/")
47 | public Stream findAllByUser(HttpServletRequest req,
48 | @PathVariable(value = "user") String user) {
49 | return repo.findByKeyUserId(user).stream()
50 | .map(TodoRestController::mapAsTodo)
51 | .map(t -> t.setUrl(req));
52 | }
53 |
54 | @GetMapping("/{user}/todos/{uid}")
55 | public ResponseEntity findById(HttpServletRequest req,
56 | @PathVariable(value = "user") String user,
57 | @PathVariable(value = "uid") String itemId) {
58 | Optional e = repo.findById(new TodoItemKey(user, UUID.fromString(itemId)));
59 | if (e.isEmpty()) {
60 | return ResponseEntity.notFound().build();
61 | }
62 | return ResponseEntity.ok(mapAsTodo(e.get()).setUrl(req.getRequestURL().toString()));
63 | }
64 |
65 | @PostMapping("/{user}/todos/")
66 | public ResponseEntity create(HttpServletRequest req,
67 | @PathVariable(value = "user") String user,
68 | @RequestBody Todo todoReq)
69 | throws URISyntaxException {
70 | TodoItem te = mapAsTodoEntity(todoReq, user);
71 | repo.save(te);
72 | todoReq.setUuid(te.getKey().getItemId());
73 | todoReq.setUrl(req);
74 | return ResponseEntity.created(new URI(todoReq.getUrl())).body(todoReq);
75 | }
76 |
77 | @PatchMapping("/{user}/todos/{uid}")
78 | public ResponseEntity update(HttpServletRequest req,
79 | @PathVariable(value = "user") String user,
80 | @PathVariable(value = "uid") String uid,
81 | @RequestBody Todo todoReq)
82 | throws URISyntaxException {
83 |
84 | // Retrieve existing task
85 | Optional todo = repo.findById(new TodoItemKey(user, UUID.fromString(uid)));
86 | if (todo.isEmpty()) return ResponseEntity.notFound().build();
87 |
88 | // Update based on provided information
89 | TodoItem item = todo.get();
90 | if (null != todoReq.getTitle() && !"".equals(todoReq.getTitle())) {
91 | item.setTitle(todoReq.getTitle());
92 | }
93 | if (null != todoReq.getOrder()) {
94 | item.setOffset(todoReq.getOrder());
95 | }
96 | item.setCompleted(todoReq.isCompleted());
97 |
98 | // Save
99 | repo.save(item);
100 | todoReq.setTitle(item.getTitle());
101 | todoReq.setUrl(req.getRequestURL().toString());
102 | todoReq.setUuid(UUID.fromString(uid));
103 | return ResponseEntity.accepted().body(todoReq);
104 | }
105 |
106 | @DeleteMapping("/{user}/todos/{uid}")
107 | public ResponseEntity deleteById(
108 | @PathVariable(value = "user") String user,
109 | @PathVariable(value = "uid") String uid) {
110 | if (!repo.existsById(new TodoItemKey(user, UUID.fromString(uid)))) {
111 | return ResponseEntity.notFound().build();
112 | }
113 | repo.deleteById(new TodoItemKey(user, UUID.fromString(uid)));
114 | return new ResponseEntity<>(HttpStatus.NO_CONTENT);
115 | }
116 |
117 | @DeleteMapping("/{user}/todos/")
118 | public ResponseEntity deleteAllByUser(@PathVariable(value = "user") String user) {
119 | repo.deleteByKeyUserId(user);
120 | return new ResponseEntity<>(HttpStatus.NO_CONTENT);
121 | }
122 |
123 | private static Todo mapAsTodo(TodoItem te) {
124 | Todo todo = new Todo();
125 | todo.setTitle(te.getTitle());
126 | todo.setOrder(te.getOffset());
127 | todo.setUuid(te.getKey().getItemId());
128 | todo.setCompleted(te.isCompleted());
129 | return todo;
130 | }
131 |
132 | private TodoItem mapAsTodoEntity(Todo te, String user) {
133 | TodoItem todo = new TodoItem();
134 | if (null != te.getUuid()) {
135 | todo.getKey().setItemId(te.getUuid());
136 | }
137 | todo.getKey().setUserId(user);
138 | todo.setTitle(te.getTitle());
139 | todo.setOffset(te.getOrder());
140 | todo.setCompleted(te.isCompleted());
141 | return todo;
142 | }
143 | }
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/resources/META-INF/additional-spring-configuration-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "properties": [
3 | {
4 | "name": "datastax.astra.secure-connect-bundle",
5 | "type": "java.lang.String",
6 | "description": "An absolute path to the Astra secure connect bundle to use."
7 | }
8 | ]
9 | }
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/resources/application.conf:
--------------------------------------------------------------------------------
1 | datastax-java-driver {
2 | basic {
3 | request {
4 | timeout = 8 seconds
5 | consistency = LOCAL_QUORUM
6 | page-size = 5000
7 | }
8 | }
9 | advanced {
10 | connection {
11 | init-query-timeout = 10 seconds
12 | set-keyspace-timeout = 10 seconds
13 | }
14 | control-connection.timeout = 10 seconds
15 | }
16 | }
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=9191
2 |
3 | spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS
4 | spring.data.cassandra.request.timeout=10s
5 | spring.data.cassandra.connection.connect-timeout=10s
6 | spring.data.cassandra.connection.init-query-timeout=10s
7 | spring.data.cassandra.keyspace-name=todos
8 | spring.data.cassandra.username=$ASTRA_USERNAME
9 | spring.data.cassandra.password=$ASTRA_PASSWORD
10 | datastax.astra.secure-connect-bundle=/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip
11 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/resources/application.properties.init:
--------------------------------------------------------------------------------
1 | server.port=9191
2 |
3 | spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS
4 | spring.data.cassandra.request.timeout=10s
5 | spring.data.cassandra.connection.connect-timeout=10s
6 | spring.data.cassandra.connection.init-query-timeout=10s
7 | spring.data.cassandra.keyspace-name=todos
8 | spring.data.cassandra.username=$ASTRA_USERNAME
9 | spring.data.cassandra.password=$ASTRA_PASSWORD
10 | datastax.astra.secure-connect-bundle=/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip
11 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/resources/banner.txt:
--------------------------------------------------------------------------------
1 | ${AnsiColor.BLUE} ________ __ __ ________ .__
2 | ${AnsiColor.BLUE} \______ \ _____ _/ |______ _______/ |______ ___ ___ \______ \ _______ __ ____ | | ____ ______ ___________ ______
3 | ${AnsiColor.BLUE} | | \\__ \\ __\__ \ / ___/\ __\__ \ \ \/ / | | \_/ __ \ \/ // __ \| | / _ \\____ \_/ __ \_ __ \/ ___/
4 | ${AnsiColor.BLUE} | ` \/ __ \| | / __ \_\___ \ | | / __ \_> < | ` \ ___/\ /\ ___/| |_( <_> ) |_> > ___/| | \/\___ \
5 | ${AnsiColor.BLUE} /_______ (____ /__| (____ /____ > |__| (____ /__/\_ \ /_______ /\___ >\_/ \___ >____/\____/| __/ \___ >__| /____ >
6 | ${AnsiColor.BLUE} \/ \/ \/ \/ \/ \/ \/ \/ \/ |__| \/ \/
7 |
8 | ${AnsiColor.CYAN} Todobackend with Spring Boot, String Data and Astra
9 | ${AnsiColor.GREEN} The application will start at ${AnsiColor.RED}http://localhost:${server.port}${AnsiColor.BLACK}
10 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | %d{HH:mm:ss.SSS} %magenta(%-5level) %cyan(%-45logger) : %msg%n
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/test/java/com/datastaxdev/Test01_Connect.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev;
2 |
3 | import java.io.File;
4 | import java.nio.file.Paths;
5 |
6 | import org.junit.jupiter.api.Assertions;
7 | import org.junit.jupiter.api.DisplayName;
8 | import org.junit.jupiter.api.Test;
9 | import org.junit.platform.runner.JUnitPlatform;
10 | import org.junit.runner.RunWith;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 | import org.springframework.beans.factory.annotation.Value;
14 | import org.springframework.test.context.TestPropertySource;
15 | import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
16 |
17 | import com.datastax.oss.driver.api.core.CqlSession;
18 |
19 | // --> Eclipse Support
20 | @SuppressWarnings("deprecation")
21 | @RunWith(JUnitPlatform.class)
22 | // <--
23 |
24 | @SpringJUnitConfig
25 | @TestPropertySource(locations="/application.properties")
26 | public class Test01_Connect {
27 |
28 | /** Logger for the class. */
29 | private static Logger LOGGER = LoggerFactory.getLogger(Test01_Connect.class);
30 |
31 | @Value("${spring.data.cassandra.username}")
32 | private String username;
33 |
34 | @Value("${spring.data.cassandra.password}")
35 | private String password;
36 |
37 | @Value("${spring.data.cassandra.keyspace-name}")
38 | private String keyspace;
39 |
40 | @Value("${datastax.astra.secure-connect-bundle}")
41 | private String cloudSecureBundle;
42 |
43 | @Test
44 | @DisplayName("Test connectivity to Astra explicit values")
45 | public void should_connect_to_Astra() {
46 |
47 | // Given interface is properly populated
48 | Assertions.assertTrue(new File(cloudSecureBundle).exists(),
49 | "File '" + cloudSecureBundle + "' has not been found\n"
50 | + "To run this sample you need to download the secure bundle file from ASTRA WebPage\n"
51 | + "More info here:");
52 |
53 | // When connecting to ASTRA
54 | try (CqlSession cqlSession = CqlSession.builder()
55 | .withCloudSecureConnectBundle(Paths.get(cloudSecureBundle))
56 | .withAuthCredentials(username, password)
57 | .withKeyspace(keyspace)
58 | .build()) {
59 |
60 | // Then connection is successfull
61 | LOGGER.info(" + [OK] - Connection Established to Astra with Keyspace {}",
62 | cqlSession.getKeyspace().get());
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/test/java/com/datastaxdev/Test02_CreateSchema.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev;
2 |
3 | import java.io.File;
4 | import java.nio.file.Paths;
5 |
6 | import org.junit.jupiter.api.Assertions;
7 | import org.junit.jupiter.api.DisplayName;
8 | import org.junit.jupiter.api.Test;
9 | import org.junit.platform.runner.JUnitPlatform;
10 | import org.junit.runner.RunWith;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 | import org.springframework.beans.factory.annotation.Value;
14 | import org.springframework.test.context.TestPropertySource;
15 | import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
16 |
17 | import com.datastax.oss.driver.api.core.CqlSession;
18 | import com.datastax.oss.driver.api.core.cql.SimpleStatement;
19 | import com.datastax.oss.driver.api.core.type.DataTypes;
20 | import com.datastax.oss.driver.api.querybuilder.SchemaBuilder;
21 |
22 | //--> Eclipse Support
23 | @SuppressWarnings("deprecation")
24 | @RunWith(JUnitPlatform.class)
25 | //<--
26 |
27 | @SpringJUnitConfig
28 | @TestPropertySource(locations="/application.properties")
29 | public class Test02_CreateSchema {
30 |
31 | /** Logger for the class. */
32 | private static Logger LOGGER = LoggerFactory.getLogger(Test02_CreateSchema.class);
33 |
34 | @Value("${spring.data.cassandra.username}")
35 | private String username;
36 |
37 | @Value("${spring.data.cassandra.password}")
38 | private String password;
39 |
40 | @Value("${spring.data.cassandra.keyspace-name}")
41 | private String keyspace;
42 |
43 | @Value("${datastax.astra.secure-connect-bundle}")
44 | private String cloudSecureBundle;
45 |
46 | @Test
47 | @DisplayName("Test to create a table in ASTRA")
48 | public void should_create_expected_table() {
49 | // Given interface is properly populated
50 | Assertions.assertTrue(new File(cloudSecureBundle).exists(),
51 | "File '" + cloudSecureBundle + "' has not been found\n"
52 | + "To run this sample you need to download the secure bundle file from ASTRA WebPage\n"
53 | + "More info here:");
54 |
55 | // When connecting to ASTRA
56 | try (CqlSession cqlSession = CqlSession.builder()
57 | .withCloudSecureConnectBundle(Paths.get(cloudSecureBundle))
58 | .withAuthCredentials(username, password)
59 | .withKeyspace(keyspace)
60 | .build()) {
61 | LOGGER.info("Connection Established to Astra with Keyspace '{}'",
62 | cqlSession.getKeyspace().get());
63 |
64 | SimpleStatement stmtDropTable = SchemaBuilder
65 | .dropTable("todoitems")
66 | .ifExists().build();
67 | // When creating the table
68 | cqlSession.execute(stmtDropTable);
69 |
70 | SimpleStatement stmtCreateTable = SchemaBuilder
71 | .createTable("todoitems")
72 | .ifNotExists()
73 | .withPartitionKey("user_id", DataTypes.TEXT)
74 | .withClusteringColumn("item_id", DataTypes.TIMEUUID)
75 | .withColumn("title", DataTypes.TEXT)
76 | .withColumn("completed", DataTypes.BOOLEAN)
77 | .withColumn("offset", DataTypes.INT)
78 | .build();
79 |
80 | // When creating the table
81 | cqlSession.execute(stmtCreateTable);
82 |
83 | // Then table is created
84 | LOGGER.info("Table '{}' has been created (if needed).", "todoitems");
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/test/java/com/datastaxdev/Test03_SaveTask.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev;
2 |
3 | import org.junit.jupiter.api.Assertions;
4 | import org.junit.jupiter.api.Test;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 |
8 | import com.datastaxdev.todo.TodoItem;
9 | import com.datastaxdev.todo.TodoItemKey;
10 | import com.datastaxdev.todo.TodoItemRepository;
11 |
12 | @SpringBootTest
13 | class Test03_SaveTask {
14 |
15 | @Autowired
16 | private TodoItemRepository repo;
17 |
18 | @Test
19 | void shoud_save_task_when_save() {
20 | // Given
21 | TodoItem te = new TodoItem("john", "Sample task1");
22 | // When
23 | repo.save(te);
24 | // then
25 | Assertions.assertTrue(repo.existsById(new TodoItemKey("john", te.getKey().getItemId())));
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/week4-api-microservices/java/src/test/java/com/datastaxdev/Test04_Controller.java:
--------------------------------------------------------------------------------
1 | package com.datastaxdev;
2 |
3 | import org.junit.jupiter.api.Assertions;
4 | import org.junit.jupiter.api.Test;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.boot.test.web.client.TestRestTemplate;
7 | import org.springframework.boot.web.server.LocalServerPort;
8 | import org.springframework.http.HttpEntity;
9 | import org.springframework.http.HttpHeaders;
10 | import org.springframework.http.HttpMethod;
11 | import org.springframework.http.HttpStatus;
12 | import org.springframework.http.ResponseEntity;
13 |
14 | import com.datastaxdev.todo.Todo;
15 |
16 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
17 | public class Test04_Controller {
18 |
19 | @LocalServerPort
20 | private int port;
21 |
22 | TestRestTemplate restTemplate = new TestRestTemplate();
23 |
24 | @Test
25 | public void should_retrieve_todolist_v1() {
26 | HttpHeaders headers = new HttpHeaders();
27 | HttpEntity entity = new HttpEntity(null, headers);
28 | ResponseEntity response = restTemplate.exchange(
29 | createURLWithPort("/api/v1/john/todos/"), HttpMethod.GET, entity, Todo[].class);
30 | Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
31 | }
32 |
33 | private String createURLWithPort(String uri) {
34 | return "http://localhost:" + port + uri;
35 | }
36 |
37 |
38 |
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/.env.example:
--------------------------------------------------------------------------------
1 | # Copy this file to .env and fill in the appropriate values. Refer to README.md
2 | # for instructions on where to find them.
3 | CQLENG_ALLOW_SCHEMA_MANAGEMENT=1
4 | ASTRA_DB_BUNDLE_PATH=bundle.zip
5 | ASTRA_DB_KEYSPACE=sag_todos
6 | ASTRA_DB_CLIENT_ID=
7 | ASTRA_DB_CLIENT_SECRET=
8 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/README.MD:
--------------------------------------------------------------------------------
1 | # 🎓🔥 API and MicroServices with Apache Cassandra - Javascript 🔥🎓
2 |
3 | 
4 |
5 | 
6 |
7 | ## Javascript Todos
8 |
9 | ## 7a - Connect to Astra
10 |
11 | ### ✅ Check connectivity parameters
12 |
13 | - Make sure you're in the right sub-directory (`javascript`) by issuing the following command in the GitPod terminal window.
14 |
15 | ```bash
16 | cd /workspace/bootcamp-fullstack-apps-with-cassandra/week4-api-microservices/javascript
17 | ```
18 |
19 | - Verify again you're in the `javascript` sub-directory using the following command
20 |
21 | ```bash
22 | pwd
23 | ```
24 |
25 | **👁️ Expected output**
26 |
27 | ```
28 | /workspace/bootcamp-fullstack-apps-with-cassandra/week4-api-microservices/javascript
29 | ```
30 |
31 | - From the GitPod terminal window issue the following command
32 |
33 | ```bash
34 | open connection.js
35 | ```
36 |
37 | and notice the following lines have been updated with the appropriate values.
38 |
39 | ```javascript
40 | // This is the "Client Id" value you obtained earlier
41 | const USERNAME = "FXXXXXXXXXXl";
42 | // This is the "Client Secret" value you obtained earlier
43 | const PASSWORD =
44 | "FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeOE.kio_.L981NQ.xq5HqXDB7s_FIJC.ssbLgbdz+G1IC0BCwIA_ZrwPrQNJWUiv26uZf2f4wo";
45 | ```
46 |
47 | ### ✅ Run the test
48 |
49 | You are ready and can now test the connection to Astra with the following command
50 |
51 | ```bash
52 | node Test01_Connect.js
53 | ```
54 |
55 | **👁️ Expected output**
56 |
57 | ```
58 | ========================================
59 | Start exercise
60 | ========================================
61 | Your are now connected to Astra 'cndb' at 'us-east1'
62 | SUCCESS
63 | ```
64 |
65 | Now that we're successfully able to establish the connection, take a moment to walk through how the connection has been established by opening the source code using the following command
66 |
67 | ```
68 | gp open Test01_Connect.js
69 | ```
70 |
71 | ## 7b - Create the schema
72 |
73 | ### ✅ Run Test
74 |
75 | Let's create the table. We will **drop** a table if it already exists with the same name.
76 |
77 | - Take a moment to review the code with the following command
78 |
79 | ```bash
80 | gp open Test02_CreateSchema.js
81 | ```
82 |
83 | - After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
84 |
85 | ```bash
86 | node Test02_CreateSchema.js
87 | ```
88 |
89 | **👁️ Expected output**
90 |
91 | ```bash
92 | ========================================
93 | Start exercise
94 | SUCCESS
95 | ========================================
96 | ```
97 |
98 | If you run into a timeout error rerun this command and confirm that the table is dropped (we changed the data model slightly so its imperative the table is dropped).
99 |
100 | ### ✅ Validate Schema with CqlSH
101 |
102 | - Open a terminal `zsh` to open a cqlsh shell (we overrided .zshrc to give you that feature)
103 |
104 | ```cql
105 | DESCRIBE KEYSPACE todos;
106 | ```
107 |
108 | **👁️ Expected output**
109 |
110 | ```cql
111 | Connected to cndb at 127.0.0.1:9042.
112 | [cqlsh 6.8.0 | Cassandra 4.0.0.6816 | CQL spec 3.4.5 | Native protocol v4]
113 | Use HELP for help.
114 | token@cqlsh> describe keyspace todos;
115 |
116 | CREATE KEYSPACE todos WITH replication = {'class': 'NetworkTopologyStrategy', 'eu-west-1': '3'} AND durable_writes = true;
117 |
118 | CREATE TABLE native_java.todoitems (
119 | user_id text,
120 | item_id timeuuid,
121 | completed boolean,
122 | offset int,
123 | title text,
124 | PRIMARY KEY (user_id, item_id)
125 | ) WITH CLUSTERING ORDER BY (item_id ASC)
126 | AND additional_write_policy = '99PERCENTILE'
127 | AND bloom_filter_fp_chance = 0.01
128 | AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
129 | AND comment = ''
130 | AND compaction = {'class': 'org.apache.cassandra.db.compaction.UnifiedCompactionStrategy'}
131 | AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
132 | AND crc_check_chance = 1.0
133 | AND default_time_to_live = 0
134 | AND gc_grace_seconds = 864000
135 | AND max_index_interval = 2048
136 | AND memtable_flush_period_in_ms = 0
137 | AND min_index_interval = 128
138 | AND read_repair = 'BLOCKING'
139 | AND speculative_retry = '99PERCENTILE';
140 |
141 | token@cqlsh>
142 | ```
143 |
144 | ## 7c - Save a Task
145 |
146 | ### ✅ Run Test
147 |
148 | Let's insert some item(s).
149 |
150 | - Take a moment to review the code with the following command
151 |
152 | ```bash
153 | gp open Test03_SaveTask.js
154 | ```
155 |
156 | - After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
157 |
158 | ```bash
159 | node Test03_SaveTask.js
160 | ```
161 |
162 | **👁️ Expected output**
163 |
164 | ```bash
165 | ========================================
166 | Start exercise
167 | SUCCESS
168 | ========================================
169 | ```
170 |
171 | ### ✅ Validate with Cqlsh
172 |
173 | - Open a terminal `cqlsh` to open a cqlsh shell (we overrided .zshrc to give you that feature)
174 |
175 | ```cql
176 | select * from todos.todoitems;
177 | ```
178 |
179 | **👁️ Expected output**
180 |
181 | ```bash
182 | token@cqlshs> select * from todos.todoitems;
183 |
184 | user_id | item_id | completed | offset | title
185 | ---------+--------------------------------------+-----------+--------+--------------
186 | john | 1793e4e0-7d65-11ec-b3f6-15c8273bc04a | False | 0 | Sample task1
187 | ```
188 |
189 | ## 7d - Test REST Endpoint
190 |
191 | ### ✅ Run Test
192 |
193 | ```bash
194 | npm test
195 | ```
196 |
197 | **👁️ Expected output**
198 |
199 | ```bash
200 | Todos
201 | ✔ it should initialize (761ms)
202 | ✔ it should create a todo (172ms)
203 | ✔ it should get todos (86ms)
204 | ✔ it should update todos (200ms)
205 | ✔ it should delete a todo (133ms)
206 | ✔ it should delete todos (615ms)
207 |
208 |
209 | 6 passing (2s)
210 | ```
211 |
212 | ## 7e - Start the application
213 |
214 | Now that we know the application is working we can go ahead and start it
215 |
216 | ### ✅ Start the application
217 |
218 | ```bash
219 | npm start
220 | ```
221 |
222 | **👁️ Expected output**
223 |
224 | ```bash
225 | > todos@0.0.1 start
226 | > node api.js
227 |
228 | Example app listening on port 8080
229 | ```
230 |
231 | ## 7f - Run the integration tests
232 |
233 | ### ✅ Open the Api in the preview
234 |
235 | Spawn a new shell (Bash is fine) while the app is running, and use it to get the full URL the API will be available at:
236 |
237 | ```bash
238 | gp preview $(gp url 8080)/api/v1/john/todos/
239 | ```
240 |
241 | You should see an empty list of todos
242 |
243 | - You might tempted to run the unit test suite now (as well you should)
244 |
245 | ```bash
246 | gp preview https://todobackend.com/specs/index.html?$(gp url 8080)/api/v1/test/todos
247 | ```
248 |
249 | You will get an error this is expected, it is a limitation of the preview in gitpod.
250 |
251 | 
252 |
253 | - Open the same link in a new tabs in your browser
254 |
255 | 
256 |
257 | ## 7g - Run the client
258 |
259 | ### ✅ Open the Client in the preview
260 |
261 | Change in the url the `specs` path by `client`
262 |
263 | ```bash
264 | gp preview https://todobackend.com/client/index.html?$(gp url 8080)/api/v1/test/todos
265 | ```
266 |
267 | 
268 |
269 | If running into the gitpod preview limitations, open the link in a new TAB.
270 |
271 | 
272 |
273 | ### ✅ Validate with cqlsh
274 |
275 | ```cql
276 | select * from todoitems;
277 | ```
278 |
279 | **👁️ Expected output**
280 |
281 | ```
282 | user_id | item_id | completed | offset | title
283 | ----------+--------------------------------------+-----------+--------+---------------------------------
284 | test | 4828ffc0-7d68-11ec-8c88-2913db53e434 | False | 523 | blah
285 | test | 483ada10-7d68-11ec-8c88-2913db53e434 | False | 95 | null
286 | test | 48625f40-7d68-11ec-8c88-2913db53e434 | False | 95 | null
287 | bootcamp | 9e6e2760-7d69-11ec-8c88-2913db53e434 | False | 1 | Week 1 - Todo
288 | bootcamp | a2fb77b0-7d69-11ec-8c88-2913db53e434 | False | 2 | Week 2 - data modelling
289 | bootcamp | a5b3b9e0-7d69-11ec-8c88-2913db53e434 | False | 3 | Week 3 - App developerment
290 | ```
291 |
292 | Congratulations! You can now head back!
293 |
294 | [BACK](../README.MD)
295 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/Test01_Connect.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | const result = await client.execute("SELECT * FROM system.local");
9 | result.rows.forEach((row) => {
10 | console.log(
11 | "Your are now connected to Astra '%s' at '%s'",
12 | row.cluster_name,
13 | row.data_center
14 | );
15 | });
16 | console.log("SUCCESS");
17 | } catch (e) {
18 | console.log(e);
19 | }
20 | console.log("========================================");
21 | process.exit();
22 | })();
23 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/Test02_CreateSchema.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | await client.execute(`DROP TABLE IF EXISTS todoitems ;`);
9 | await client.execute(`
10 | CREATE TABLE IF NOT EXISTS todoitems (
11 | user_id TEXT,
12 | item_id TIMEUUID,
13 | title TEXT,
14 | url TEXT,
15 | completed BOOLEAN,
16 | offset INT,
17 | PRIMARY KEY ((user_id), item_id)
18 | ) WITH CLUSTERING ORDER BY (item_id ASC);`);
19 | console.log("SUCCESS");
20 | } catch (e) {
21 | console.log(e);
22 | }
23 | console.log("========================================");
24 | process.exit();
25 | })();
26 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/Test03_SaveTask.js:
--------------------------------------------------------------------------------
1 | const { client } = require("./connection");
2 |
3 | console.log("========================================");
4 | console.log("Start exercise");
5 |
6 | (async () => {
7 | try {
8 | await client.execute(
9 | "INSERT INTO todoitems (user_id, item_id, completed, title, offset) VALUES ( 'john', 11111111-5cff-11ec-be16-1fedb0dfd057, true, 'Walk the dog', 0);"
10 | );
11 |
12 | console.log("SUCCESS");
13 | } catch (e) {
14 | console.log(e);
15 | }
16 | console.log("========================================");
17 | process.exit();
18 | })();
19 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/api.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const app = express();
3 | const cors = require("cors");
4 | const morgan = require("morgan");
5 | const todos = require("./todos");
6 |
7 | const port = 8080;
8 |
9 | app.use(express.json());
10 | app.use(cors());
11 | app.use(morgan("dev"));
12 |
13 | app.get("/api/v1/:userId/todos", async (req, res) => {
14 | const todoRes = await todos.getTodos(req.params.userId);
15 | res.json(todoRes);
16 | });
17 |
18 | app.get("/api/v1/:userId/todos/:itemId", async (req, res) => {
19 | const todoRes = await todos.getTodo(req.params.userId, req.params.itemId);
20 | res.json(todoRes);
21 | });
22 |
23 | app.post("/api/v1/:userId/todos", async (req, res) => {
24 | const todoRes = await todos.createTodo({
25 | ...req.body,
26 | url: `https://${req.hostname}${req.originalUrl}`,
27 | user_id: req.params.userId,
28 | });
29 | res.json(todoRes);
30 | });
31 |
32 | app.patch("/api/v1/:userId/todos/:itemId", async (req, res) => {
33 | const todoRes = await todos.updateTodo(req.params.userId, req.params.itemId, {
34 | ...req.body,
35 | });
36 | res.json(todoRes);
37 | });
38 |
39 | app.delete("/api/v1/:userId/todos/:itemId", async (req, res) => {
40 | const todoRes = await todos.deleteTodo(req.params.userId, req.params.itemId);
41 | res.json(todoRes);
42 | });
43 |
44 | app.delete("/api/v1/:userId/todos", async (req, res) => {
45 | const todoRes = await todos.deleteTodos();
46 | res.json(todoRes);
47 | });
48 |
49 | app.listen(port, async () => {
50 | await todos.init();
51 | console.log(`Example app listening on port ${port}`);
52 | });
53 |
54 | module.exports = app;
55 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/connection.js:
--------------------------------------------------------------------------------
1 | // WARNING: THIS FILE IS GOING TO BE OVERWRITTEN
2 | const cassandra = require("cassandra-driver");
3 |
4 | // This is the Zip file you downloaded
5 | const SECURE_CONNECT_BUNDLE =
6 | "/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip";
7 | // This is the "Client Id" value you obtained earlier
8 | const USERNAME = "";
9 | // This is the "Client Secret" value you obtained earlier
10 | const PASSWORD = "";
11 | // This is the keyspace name
12 | const KEYSPACE = "todos";
13 |
14 | const client = new cassandra.Client({
15 | cloud: { secureConnectBundle: SECURE_CONNECT_BUNDLE },
16 | keyspace: KEYSPACE,
17 | credentials: { username: USERNAME, password: PASSWORD },
18 | });
19 |
20 | process.on("exit", () => client.shutdown());
21 |
22 | module.exports = {
23 | client,
24 | };
25 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/connection.js.init:
--------------------------------------------------------------------------------
1 | // THIS FILE WILL BE OVERWRITTEN. DO NOT MAKE ANY CHANGES
2 | const cassandra = require("cassandra-driver");
3 |
4 | // This is the Zip file you downloaded
5 | const SECURE_CONNECT_BUNDLE =
6 | "/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip";
7 | // This is the "Client Id" value you obtained earlier
8 | const USERNAME = "$ASTRA_USERNAME";
9 | // This is the "Client Secret" value you obtained earlier
10 | const PASSWORD = "$ASTRA_PASSWORD";
11 | // This is the keyspace name
12 | const KEYSPACE = "todos";
13 |
14 | const client = new cassandra.Client({
15 | cloud: { secureConnectBundle: SECURE_CONNECT_BUNDLE },
16 | keyspace: KEYSPACE,
17 | credentials: { username: USERNAME, password: PASSWORD },
18 | });
19 |
20 | process.on("exit", () => client.shutdown());
21 |
22 | module.exports = {
23 | client,
24 | };
25 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "todos",
3 | "version": "0.0.1",
4 | "main": "api.js",
5 | "scripts": {
6 | "start": "node api.js",
7 | "test": "mocha *.test.js --timeout 30000 --exit"
8 | },
9 | "devDependencies": {
10 | "mocha": "^9.2.0"
11 | },
12 | "dependencies": {
13 | "cassandra-driver": "^4.6.3",
14 | "cors": "^2.8.5",
15 | "dotenv": "^14.2.0",
16 | "express": "^4.17.2",
17 | "morgan": "^1.10.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/todos.js:
--------------------------------------------------------------------------------
1 | require("dotenv").config();
2 | const { client } = require("./connection");
3 | const cassandra = require("cassandra-driver");
4 |
5 | let todoMapper = null;
6 |
7 | process.on("exit", () => client.shutdown());
8 |
9 | module.exports = {
10 | client,
11 | todoMapper,
12 | init: async () => {
13 | await client.connect();
14 | await client.execute(`CREATE TABLE IF NOT EXISTS todoitems (
15 | user_id TEXT,
16 | item_id TIMEUUID,
17 | title TEXT,
18 | url TEXT,
19 | completed BOOLEAN,
20 | offset INT,
21 | PRIMARY KEY ((user_id), item_id)
22 | ) WITH CLUSTERING ORDER BY (item_id ASC);`);
23 |
24 | const mapper = new cassandra.mapping.Mapper(client, {
25 | models: {
26 | Todos: {
27 | tables: ["todoitems"],
28 | keyspace: process.env.ASTRA_DB_KEYSPACE,
29 | columns: {
30 | offset: "order",
31 | },
32 | },
33 | },
34 | });
35 | todoMapper = mapper.forModel("Todos");
36 | },
37 | getTodos: async (userId) => {
38 | const res = await todoMapper.find({ user_id: userId });
39 | if (res.length) {
40 | return res
41 | .toArray()
42 | .map((item) => ({ ...item, item_id: item.item_id.toString() }));
43 | }
44 | return [];
45 | },
46 | deleteTodos: async () => {
47 | await client.execute("TRUNCATE TABLE todoitems");
48 | return [];
49 | },
50 | createTodo: async (todo) => {
51 | const item_id = cassandra.types.TimeUuid.now().toString();
52 | const newTodo = {
53 | item_id,
54 | completed: false,
55 | ...todo,
56 | url: todo.url + "/" + item_id,
57 | };
58 | await todoMapper.insert(newTodo);
59 | return newTodo;
60 | },
61 | updateTodo: async (userId, itemId, todo) => {
62 | const updatedTodo = {
63 | user_id: userId,
64 | item_id: itemId,
65 | ...todo,
66 | };
67 | await todoMapper.update(updatedTodo);
68 | return updatedTodo;
69 | },
70 | deleteTodo: async (userId, itemId) => {
71 | await todoMapper.remove({ user_id: userId, item_id: itemId });
72 | return {
73 | userId,
74 | itemId,
75 | };
76 | },
77 | getTodo: async (userId, itemId) => {
78 | const res = await todoMapper.get({ user_id: userId, item_id: itemId });
79 | if (res) {
80 | return { ...res, item_id: res.item_id.toString() };
81 | }
82 | return null;
83 | },
84 | };
85 |
--------------------------------------------------------------------------------
/week4-api-microservices/javascript/todos.test.js:
--------------------------------------------------------------------------------
1 | const assert = require("assert");
2 | const todos = require("./todos");
3 |
4 | describe("Todos", () => {
5 | it("it should initialize", async () => {
6 | await todos.init();
7 | assert.equal(true, true);
8 | });
9 |
10 | it("it should create a todo", async () => {
11 | const todo = await todos.createTodo({
12 | user_id: "jake",
13 | title: "hello world",
14 | });
15 | assert.equal(todo.title, "hello world");
16 | });
17 |
18 | it("it should get todos", async () => {
19 | const res = await todos.getTodos("jake");
20 | assert.equal(res.length, 1);
21 | });
22 |
23 | it("it should update todos", async () => {
24 | const res = await todos.getTodos("jake");
25 | const existingTodo = res[0];
26 | await todos.updateTodo("jake", existingTodo.item_id, {
27 | title: "hello world 2",
28 | });
29 | const todo = await todos.getTodo("jake", existingTodo.item_id);
30 | assert.equal(todo.title, "hello world 2");
31 | });
32 |
33 | it("it should delete a todo", async () => {
34 | const res = await todos.getTodos("jake");
35 | const existingTodo = res[0];
36 | await todos.deleteTodo("jake", existingTodo.item_id);
37 | const todo = await todos.getTodo("jake", existingTodo.item_id);
38 | assert.equal(todo, null);
39 | });
40 |
41 | it("it should delete todos", async () => {
42 | await todos.deleteTodos();
43 | assert.equal(true, true);
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/week4-api-microservices/plugastracreds:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ ! -f .env ]; then
4 | echo "File .env needs to exist."
5 | exit -1
6 | fi
7 |
8 | source .env
9 |
10 | if [ ! "$ASTRA_USERNAME" ]; then
11 | echo "env variable ASTRA_USERNAME needs to be set"
12 | exit -1
13 | fi
14 |
15 | if [ ! "$ASTRA_PASSWORD" ]; then
16 | echo "env variable ASTRA_PASSWORD needs to be set"
17 | exit -1
18 | fi
19 |
20 | if [ ! -f /workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip ]; then
21 | echo "Secure connect bundle to connect to Astra does not exist."
22 | exit -1
23 | fi
24 |
25 | cat ./java/src/main/resources/application.properties.init | \
26 | sed "s/\$ASTRA_USERNAME/$ASTRA_USERNAME/" | \
27 | sed "s/\$ASTRA_PASSWORD/$ASTRA_PASSWORD/" > \
28 | ./java/src/main/resources/application.properties
29 |
30 | cat ./javascript/connection.js.init | \
31 | sed "s/\$ASTRA_USERNAME/$ASTRA_USERNAME/" | \
32 | sed "s/\$ASTRA_PASSWORD/$ASTRA_PASSWORD/" > \
33 | ./javascript/connection.js
34 |
35 | cat ./python/connection.py.init | \
36 | sed "s/\$ASTRA_USERNAME/$ASTRA_USERNAME/" | \
37 | sed "s/\$ASTRA_PASSWORD/$ASTRA_PASSWORD/" > \
38 | ./python/connection.py
39 |
40 | echo "Astra credentials plugged into all language environments. Please verify!"
41 |
42 | if [ ! -f /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit ]; then
43 | cp ~/.zshrc /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit
44 | echo "/workspace/bootcamp-fullstack-apps-with-cassandra/cqlsh-astra/bin/cqlsh \\
45 | --secure-connect-bundle=/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip \\
46 | --color \\
47 | -u $ASTRA_USERNAME \\
48 | -p $ASTRA_PASSWORD" >> /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit
49 | cp /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit ~/.zshrc
50 | else
51 | cp /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit ~/.zshrc
52 | fi
53 |
54 | touch /workspace/bootcamp-fullstack-apps-with-cassandra/zshrcinit
55 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/.env.example:
--------------------------------------------------------------------------------
1 | # Copy this file to .env and fill in the appropriate values. Refer to README.md
2 | # for instructions on where to find them.
3 | FLASK_APP=api
4 | CQLENG_ALLOW_SCHEMA_MANAGEMENT=1
5 | ASTRA_DB_BUNDLE_PATH=bundle.zip
6 | ASTRA_DB_KEYSPACE=sag_todos
7 | ASTRA_DB_CLIENT_ID=
8 | ASTRA_DB_CLIENT_SECRET=
--------------------------------------------------------------------------------
/week4-api-microservices/python/README.MD:
--------------------------------------------------------------------------------
1 | # 🎓🔥 API and MicroServices with Apache Cassandra - Python 🔥🎓
2 |
3 | 
4 |
5 | 
6 |
7 | ## Python Todos
8 |
9 | An implementation of a Todo's API using ExpressJS and the Cassandra Python driver.
10 |
11 |
12 | ## 7a - Connect to Astra
13 |
14 | ### ✅ Check connectivity parameters
15 |
16 | - Make sure you're in the right sub-directory (`python`) by issuing the following command in the GitPod terminal window.
17 |
18 | ```bash
19 | cd /workspace/bootcamp-fullstack-apps-with-cassandra/week4-api-microservices/python
20 | ```
21 |
22 | - Verify again you're in the `python` sub-directory using the following command
23 |
24 | ```bash
25 | pwd
26 | ```
27 |
28 | **👁️ Expected output**
29 |
30 | ```
31 | /workspace/bootcamp-fullstack-apps-with-cassandra/week4-api-microservices/python
32 | ```
33 |
34 | - From the GitPod terminal window issue the following command
35 |
36 | ```bash
37 | open connection.py
38 | ```
39 |
40 | and notice the following lines have been updated with the appropriate values.
41 |
42 | ```python
43 | # This is the "Client Id" value you obtained earlier
44 | USERNAME = "FXXXXXXXXXXl";
45 | # This is the "Client Secret" value you obtained earlier
46 | PASSWORD =
47 | "FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeOE.kio_.L981NQ.xq5HqXDB7s_FIJC.ssbLgbdz+G1IC0BCwIA_ZrwPrQNJWUiv26uZf2f4wo";
48 | ```
49 |
50 | ### ✅ Run the test
51 |
52 | You are ready and can now test the connection to Astra with the following command
53 |
54 | ```bash
55 | python Test01_Connect.py
56 | ```
57 |
58 | **👁️ Expected output**
59 |
60 | ```
61 | ========================================
62 | Start exercise
63 | ========================================
64 | Your are now connected to Astra 'cndb' at 'us-east1'
65 | SUCCESS
66 | ```
67 |
68 | Now that we're successfully able to establish the connection, take a moment to walk through how the connection has been established by opening the source code using the following command
69 |
70 | ```
71 | gp open Test01_Connect.py
72 | ```
73 |
74 | ## 7b - Create the schema
75 |
76 | ### ✅ Run Test
77 |
78 | Let's create the table. We will **drop** a table if it already exists with the same name.
79 |
80 | - Take a moment to review the code with the following command
81 |
82 | ```bash
83 | gp open Test02_CreateSchema.py
84 | ```
85 |
86 | - After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
87 |
88 | ```bash
89 | python Test02_CreateSchema.py
90 | ```
91 |
92 | **👁️ Expected output**
93 |
94 | ```bash
95 | ========================================
96 | Start exercise
97 | SUCCESS
98 | ========================================
99 | ```
100 |
101 | If you run into a timeout error rerun this command and confirm that the table is dropped (we changed the data model slightly so its imperative the table is dropped).
102 |
103 | ### ✅ Validate Schema with Cqlsh
104 |
105 | - Open a terminal `cqlsh` to open a cqlsh shell (we overrided .zshrc to give you that feature)
106 |
107 | ```cql
108 | DESCRIBE KEYSPACE todos;
109 | ```
110 |
111 | **👁️ Expected output**
112 |
113 | ```cql
114 | Connected to cndb at 127.0.0.1:9042.
115 | [cqlsh 6.8.0 | Cassandra 4.0.0.6816 | CQL spec 3.4.5 | Native protocol v4]
116 | Use HELP for help.
117 | token@cqlsh> describe keyspace todos;
118 |
119 | CREATE KEYSPACE todos WITH replication = {'class': 'NetworkTopologyStrategy', 'eu-west-1': '3'} AND durable_writes = true;
120 |
121 | CREATE TABLE todos.todoitems (
122 | user_id text,
123 | item_id timeuuid,
124 | completed boolean,
125 | offset int,
126 | title text,
127 | PRIMARY KEY (user_id, item_id)
128 | ) WITH CLUSTERING ORDER BY (item_id ASC)
129 | AND additional_write_policy = '99PERCENTILE'
130 | AND bloom_filter_fp_chance = 0.01
131 | AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
132 | AND comment = ''
133 | AND compaction = {'class': 'org.apache.cassandra.db.compaction.UnifiedCompactionStrategy'}
134 | AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
135 | AND crc_check_chance = 1.0
136 | AND default_time_to_live = 0
137 | AND gc_grace_seconds = 864000
138 | AND max_index_interval = 2048
139 | AND memtable_flush_period_in_ms = 0
140 | AND min_index_interval = 128
141 | AND read_repair = 'BLOCKING'
142 | AND speculative_retry = '99PERCENTILE';
143 |
144 | token@cqlsh>
145 | ```
146 |
147 | ## 7c - Save a Task
148 |
149 | ### ✅ Run Test
150 |
151 | Let's insert some items.
152 |
153 | - Take a moment to review the code with the following command
154 |
155 | ```bash
156 | gp open Test03_SaveTask.py
157 | ```
158 |
159 | - After reviewing the code, run the following command in the GitPod terminal window which runs the code after making the connection.
160 |
161 | ```bash
162 | python Test03_SaveTask.py
163 | ```
164 |
165 | **👁️ Expected output**
166 |
167 | ```bash
168 | ========================================
169 | Start exercise
170 | SUCCESS
171 | ========================================
172 | ```
173 |
174 | ### ✅ Validate with Cqlsh
175 |
176 | - Open a terminal `zsh` to open a cqlsh shell (we overrided .zshrc to give you that feature)
177 |
178 | ```cql
179 | select * from todos.todoitems;
180 | ```
181 |
182 | **👁️ Expected output**
183 |
184 | ```bash
185 | token@cqlshs> select * from todos.todoitems;
186 |
187 | user_id | item_id | completed | offset | title
188 | ---------+--------------------------------------+-----------+--------+--------------
189 | john | 1793e4e0-7d65-11ec-b3f6-15c8273bc04a | False | 0 | Sample task1
190 | ```
191 |
192 | ## 7d - Test REST Endpoint
193 |
194 | ### ✅ Run Test
195 |
196 | ```bash
197 | pytest
198 | ```
199 |
200 | **👁️ Expected output**
201 |
202 | ```bash
203 | collected 13 items
204 |
205 | test_api.py::test_get_empty_todos
206 | api
207 | ✓ it should get an empty list of todos
208 |
209 | test_api.py::test_create_todo ✓ it should create a todo
210 |
211 | test_api.py::test_not_create_todo ✓ it should not create a todo
212 |
213 | test_api.py::test_get_todo ✓ it should get a single todo
214 |
215 | test_api.py::test_not_get_todo ✓ it should not get a single todo
216 |
217 | test_api.py::test_get_todos ✓ it should get a list of todos
218 |
219 | test_api.py::test_delete_todo ✓ it should delete a single todo
220 |
221 | test_api.py::test_update_todo ✓ it should update a single todo
222 |
223 | test_api.py::test_delete_all_todos ✓ it should delete all todos
224 |
225 | test_todos.py::test_create_todo
226 | todos
227 | ✓ it should create a todo
228 |
229 | test_todos.py::test_delete_todo ✓ it should delete a single todo
230 |
231 | test_todos.py::test_update_todo ✓ it should update a single todo
232 |
233 | test_todos.py::test_delete_all_todos ✓ it should delete all todos
234 |
235 |
236 | ---------- coverage: platform darwin, python 3.9.4-final-0 -----------
237 | Name Stmts Miss Cover Missing
238 | ------------------------------------------------------
239 | Test01_Connect.py 12 12 0% 2-16
240 | Test02_CreateSchema.py 11 11 0% 2-22
241 | Test03_SaveTask.py 11 11 0% 2-15
242 | api.py 54 0 100%
243 | connection.py 15 2 87% 35-36
244 | test_api.py 67 0 100%
245 | test_todos.py 24 1 96% 18
246 | todos.py 20 0 100%
247 | ------------------------------------------------------
248 | TOTAL 214 37 83%
249 | ```
250 |
251 | ## 7e - Start the application
252 |
253 | Now that we know the application is working we can go ahead and start it
254 |
255 | ### ✅ Start the application
256 |
257 | ```bash
258 | FLASK_APP=api:app flask run --port 8080
259 | ```
260 |
261 | **👁️ Expected output**
262 |
263 | ```bash
264 | * Serving Flask app 'api' (lazy loading)
265 | * Environment: production
266 | WARNING: This is a development server. Do not use it in a production deployment.
267 | Use a production WSGI server instead.
268 | * Debug mode: off
269 | * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
270 | ```
271 |
272 | ## 7f - Run the integrations tests
273 |
274 | ### ✅ Open the Api in the preview
275 |
276 | (while the API is running you should use another Gitpod terminal to run other commands)
277 |
278 | ```bash
279 | gp preview $(gp url 8080)/api/v1/john/todos/
280 | ```
281 |
282 | You should see an empty list of todos
283 |
284 | - You might tempted to run the unit test suite now (as well you should)
285 |
286 | ```bash
287 | gp preview https://todobackend.com/specs/index.html?$(gp url 8080)/api/v1/test/todos
288 | ```
289 |
290 | You will get an error this is expected, it is a limitation of the preview in gitpod.
291 |
292 | 
293 |
294 | - Open the same link in a new tabs in your browser
295 |
296 | 
297 |
298 | ## 7g - Run the client
299 |
300 | ### ✅ Open the Client in the preview
301 |
302 | Change in the url the `specs` path by `client`
303 |
304 | ```bash
305 | gp preview https://todobackend.com/client/index.html?$(gp url 8080)/api/v1/test/todos
306 | ```
307 |
308 | 
309 |
310 | If running into the gitpod preview limitations, open the link in a new TAB.
311 |
312 | 
313 |
314 | ### ✅ Validate with cqlsh
315 |
316 | ```cql
317 | select * from todoitems;
318 | ```
319 |
320 | **👁️ Expected output**
321 |
322 | ```
323 | user_id | item_id | completed | offset | title
324 | ----------+--------------------------------------+-----------+--------+---------------------------------
325 | test | 4828ffc0-7d68-11ec-8c88-2913db53e434 | False | 523 | blah
326 | test | 483ada10-7d68-11ec-8c88-2913db53e434 | False | 95 | null
327 | test | 48625f40-7d68-11ec-8c88-2913db53e434 | False | 95 | null
328 | bootcamp | 9e6e2760-7d69-11ec-8c88-2913db53e434 | False | 1 | Week 1 - Todo
329 | bootcamp | a2fb77b0-7d69-11ec-8c88-2913db53e434 | False | 2 | Week 2 - data modelling
330 | bootcamp | a5b3b9e0-7d69-11ec-8c88-2913db53e434 | False | 3 | Week 3 - App developerment
331 | ```
332 |
333 | Congratulations! You can now head back!
334 |
335 | [BACK](../README.MD)
336 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/Test01_Connect.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from connection import session
3 |
4 | print('========================================')
5 | print('Start exercise')
6 | try:
7 | output = session.execute("SELECT * FROM system.local")
8 | for row in output:
9 | print('You are now connected to cluster %s at %s' %
10 | (row.cluster_name, row.data_center))
11 | except Exception as e:
12 | print(e)
13 | print('Failure')
14 | else:
15 | print('Success')
16 | print('========================================')
17 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/Test02_CreateSchema.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from connection import session
3 |
4 | print('========================================')
5 | print('Start exercise by dropping and creating table')
6 | try:
7 | session.execute("""DROP TABLE IF EXISTS todoitems;""")
8 | session.execute("""CREATE TABLE IF NOT EXISTS todoitems (
9 | user_id TEXT,
10 | item_id TIMEUUID,
11 | title TEXT,
12 | url TEXT,
13 | completed BOOLEAN,
14 | offset INT,
15 | PRIMARY KEY ((user_id), item_id)
16 | ) WITH CLUSTERING ORDER BY (item_id ASC);
17 | """)
18 | except Exception as e:
19 | print(e)
20 | print('Failure')
21 | else:
22 | print('Success')
23 | print('========================================')
24 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/Test03_SaveTask.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import uuid
3 | from connection import session
4 |
5 | print('========================================')
6 | print('Start exercise')
7 | try:
8 | session.execute(
9 | "INSERT INTO todoitems (user_id, item_id, completed, title, offset) VALUES ( 'john', 11111111-5cff-11ec-be16-1fedb0dfd057, true, 'Walk the dog', 0);")
10 | except Exception as e:
11 | print(e)
12 | print('Failure')
13 | else:
14 | print('Success')
15 | print('========================================')
16 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/api.py:
--------------------------------------------------------------------------------
1 | import uuid
2 | from dotenv import load_dotenv
3 | from cassandra.cqlengine.management import sync_table
4 | from cassandra.cqlengine import ValidationError
5 | from cassandra.cqlengine.models import Model
6 | from flask import Flask, jsonify, request
7 | from todos import Todos, session, KEYSPACE
8 | from flask_cors import CORS
9 |
10 | load_dotenv()
11 |
12 |
13 | # setup flask
14 | app = Flask(__name__)
15 | CORS(app, resources={r"/api/*": {"origins": "*"}})
16 |
17 |
18 | @app.route("/api/v1//todos", methods=["GET"])
19 | def get_todos(user_id):
20 | res = [dict(x) for x in Todos.filter(user_id=user_id)]
21 | return jsonify(res)
22 |
23 |
24 | @app.route("/api/v1//todos", methods=["DELETE"])
25 | def delete_todos(user_id):
26 | session.execute(
27 | f"TRUNCATE TABLE {KEYSPACE}.todoitems")
28 | sync_table(Todos)
29 | return jsonify({"success": True})
30 |
31 |
32 | @app.route("/api/v1//todos", methods=["POST"])
33 | def create_todo(user_id):
34 | try:
35 | request_json = request.get_json(force=True)
36 | item_id = uuid.uuid1()
37 | request_json["item_id"] = item_id
38 | request_json["url"] = f"https://{request.headers.get('X-Forwarded-Host', 'localhost')}/api/v1/{user_id}/todos/{item_id}"
39 | new_todo = Todos.create(user_id=user_id, **request_json)
40 | return jsonify(dict(new_todo))
41 | except ValidationError as e:
42 | return jsonify({"error": str(e)}), 400
43 |
44 |
45 | @app.route("/api/v1//todos/", methods=["GET"])
46 | def get_todo(user_id, item_id):
47 | try:
48 | todo = Todos.get(user_id=user_id, item_id=item_id)
49 | return jsonify(dict(todo))
50 | except Model.DoesNotExist:
51 | return jsonify({"error": "not found"}), 404
52 |
53 |
54 | @app.route("/api/v1//todos/", methods=["DELETE"])
55 | def delete_todo(user_id, item_id):
56 | try:
57 | todo = Todos.get(user_id=user_id, item_id=item_id)
58 | todo.delete()
59 | return jsonify(dict(todo))
60 | except Model.DoesNotExist:
61 | return jsonify({"error": "not found"}), 404
62 |
63 |
64 | @app.route("/api/v1//todos/", methods=["PATCH"])
65 | def update_todo(user_id, item_id):
66 | try:
67 | todo = Todos.get(user_id=user_id, item_id=item_id)
68 | request_json = request.get_json(force=True)
69 | todo.update(**request_json)
70 | return jsonify(dict(todo))
71 | except Model.DoesNotExist:
72 | return jsonify({"error": "not found"}), 404
73 | except ValidationError as e:
74 | return jsonify({"error": str(e)}), 400
75 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/connection.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # THIS FILE WILL BE OVERWRITTEN. DO NOT MAKE ANY CHANGES HERE
3 |
4 | import atexit
5 | from cassandra.cluster import Cluster
6 | from cassandra.auth import PlainTextAuthProvider
7 |
8 | # This is the Zip file you downloaded
9 | SECURE_CONNECT_BUNDLE = '/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip'
10 | # This is the "Client Id" value you obtained earlier
11 | USERNAME = ""
12 | # This is the "Client Secret" value you obtained earlier
13 | PASSWORD = ""
14 | # This is the keyspace name
15 | KEYSPACE = "todos"
16 |
17 |
18 | secure_connect_bundle = SECURE_CONNECT_BUNDLE
19 | path_to_creds = ''
20 | cluster = Cluster(
21 | cloud={
22 | 'secure_connect_bundle': SECURE_CONNECT_BUNDLE
23 | },
24 | auth_provider=PlainTextAuthProvider(USERNAME, PASSWORD)
25 | )
26 | session = cluster.connect(KEYSPACE)
27 |
28 |
29 | @atexit.register
30 | def shutdown_driver():
31 | cluster.shutdown()
32 | session.shutdown()
33 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/connection.py.init:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # THIS FILE WILL BE OVERWRITTEN. DO NOT MAKE ANY CHANGES HERE
3 |
4 | import atexit
5 | from cassandra.cluster import Cluster
6 | from cassandra.auth import PlainTextAuthProvider
7 |
8 | # This is the Zip file you downloaded
9 | SECURE_CONNECT_BUNDLE = '/workspace/bootcamp-fullstack-apps-with-cassandra/secure-connect-workshops.zip'
10 | # This is the "Client Id" value you obtained earlier
11 | USERNAME = "$ASTRA_USERNAME"
12 | # This is the "Client Secret" value you obtained earlier
13 | PASSWORD = "$ASTRA_PASSWORD"
14 | # This is the keyspace name
15 | KEYSPACE = "todos"
16 |
17 |
18 | secure_connect_bundle = SECURE_CONNECT_BUNDLE
19 | path_to_creds = ''
20 | cluster = Cluster(
21 | cloud={
22 | 'secure_connect_bundle': SECURE_CONNECT_BUNDLE
23 | },
24 | auth_provider=PlainTextAuthProvider(USERNAME, PASSWORD)
25 | )
26 | session = cluster.connect(KEYSPACE)
27 |
28 |
29 | @atexit.register
30 | def shutdown_driver():
31 | cluster.shutdown()
32 | session.shutdown()
33 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | filterwarnings = ignore::DeprecationWarning
3 | addopts = -v --cov=. --cov-report term-missing --testdox
4 | log_cli = 1
5 | log_cli_level = INFO
--------------------------------------------------------------------------------
/week4-api-microservices/python/requirements.txt:
--------------------------------------------------------------------------------
1 | flask==2.0.2
2 | python-dotenv==0.19.2
3 | cassandra-driver==3.25.0
4 | pytest==6.2.5
5 | pytest-cov==3.0.0
6 | pytest-testdox==3.0.0
7 | flask-cors==3.0.10
8 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/test_api.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | import uuid
3 | from api import app
4 |
5 | USER_ID = "jake"
6 |
7 | with app.test_client() as client:
8 | @pytest.mark.it("it should get an empty list of todos")
9 | def test_get_empty_todos():
10 | get_res = client.get(f"/api/v1/{USER_ID}/todos")
11 | get_res_json = get_res.get_json()
12 | assert len(get_res_json) == 0
13 |
14 | @pytest.mark.it("it should create a todo")
15 | def test_create_todo():
16 | res = client.post(f"/api/v1/{USER_ID}/todos",
17 | json={"title": "hello world"})
18 | res_json = res.get_json()
19 | assert res_json["title"] == "hello world"
20 |
21 | @pytest.mark.it("it should not create a todo")
22 | def test_not_create_todo():
23 | res = client.post(f"/api/v1/{USER_ID}/todos", json={"title": ""})
24 | assert res.status_code == 400
25 |
26 | @pytest.mark.it("it should get a single todo")
27 | def test_get_todo():
28 | res = client.post(f"/api/v1/{USER_ID}/todos",
29 | json={"title": "hello world 2"})
30 | res_json = res.get_json()
31 | get_res = client.get(f"/api/v1/{USER_ID}/todos/{res_json['item_id']}")
32 | get_res_json = get_res.get_json()
33 | assert get_res_json["title"] == "hello world 2"
34 |
35 | @pytest.mark.it("it should not get a single todo")
36 | def test_not_get_todo():
37 | get_res = client.get(f"/api/v1/{USER_ID}/todos/{uuid.uuid1()}")
38 | assert get_res.status_code == 404
39 |
40 | @pytest.mark.it("it should get a list of todos")
41 | def test_get_todos():
42 | get_res = client.get(f"/api/v1/{USER_ID}/todos")
43 | get_res_json = get_res.get_json()
44 | assert len(get_res_json) == 2
45 |
46 | @pytest.mark.it("it should delete a single todo")
47 | def test_delete_todo():
48 | res = client.post(f"/api/v1/{USER_ID}/todos",
49 | json={"title": "hello world 3"})
50 | res_json = res.get_json()
51 | delete_res = client.delete(
52 | f"/api/v1/{USER_ID}/todos/{res_json['item_id']}")
53 | delete_res_json = delete_res.get_json()
54 | assert delete_res_json["title"] == "hello world 3"
55 | get_res = client.get(f"/api/v1/{USER_ID}/todos/{res_json['item_id']}")
56 | assert get_res.status_code == 404
57 | del_res = client.delete(
58 | f"/api/v1/{USER_ID}/todos/{res_json['item_id']}")
59 | assert del_res.status_code == 404
60 |
61 | @pytest.mark.it("it should update a single todo")
62 | def test_update_todo():
63 | res = client.post(f"/api/v1/{USER_ID}/todos",
64 | json={"title": "hello world 4"})
65 | res_json = res.get_json()
66 | patch_res = client.patch(
67 | f"/api/v1/{USER_ID}/todos/{res_json['item_id']}", json={"completed": True})
68 | assert patch_res.status_code == 200
69 | get_res = client.get(f"/api/v1/{USER_ID}/todos/{res_json['item_id']}")
70 | get_res_json = get_res.get_json()
71 | assert get_res_json["completed"] == True
72 | bad_res = client.patch(
73 | f"/api/v1/{USER_ID}/todos/{res_json['item_id']}", json={"title": ""})
74 | assert bad_res.status_code == 400
75 | missing_res = client.patch(f"/api/v1/{USER_ID}/todos/{uuid.uuid1()}")
76 | assert missing_res.status_code == 404
77 |
78 | @pytest.mark.it("it should delete all todos")
79 | def test_delete_all_todos():
80 | delete_res = client.delete(f"/api/v1/{USER_ID}/todos")
81 | delete_res_json = delete_res.get_json()
82 | assert delete_res_json["success"] == True
83 | get_res = client.get(f"/api/v1/{USER_ID}/todos")
84 | get_res_json = get_res.get_json()
85 | assert get_res_json == []
86 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/test_todos.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | import os
3 | from todos import Todos, session, KEYSPACE
4 |
5 |
6 | @pytest.mark.it("it should create a todo")
7 | def test_create_todo():
8 | todo = Todos.create(user_id="jake", title="hello world")
9 | assert todo.title == "hello world"
10 |
11 |
12 | @pytest.mark.it("it should delete a single todo")
13 | def test_delete_todo():
14 | todo = Todos.create(user_id="jake", title="hello world 2")
15 | todo.delete()
16 | try:
17 | todo = Todos.get(user_id="jake", item_id=todo.item_id)
18 | assert False
19 | except:
20 | assert True
21 |
22 |
23 | @pytest.mark.it("it should update a single todo")
24 | def test_update_todo():
25 | todo = Todos.create(user_id="jake", title="hello world 3")
26 | todo.update(title="hello world 4")
27 | assert todo.title == "hello world 4"
28 |
29 |
30 | @pytest.mark.it("it should delete all todos")
31 | def test_delete_all_todos():
32 | session.execute(
33 | f"TRUNCATE TABLE {KEYSPACE}.todoitems")
34 |
--------------------------------------------------------------------------------
/week4-api-microservices/python/todos.py:
--------------------------------------------------------------------------------
1 | import os
2 | import uuid
3 | from dotenv import load_dotenv
4 | from cassandra.cqlengine import columns
5 | from cassandra.cqlengine.models import Model
6 | from cassandra.cqlengine.management import sync_table
7 | from cassandra.cqlengine import connection
8 | from connection import session, KEYSPACE
9 |
10 | load_dotenv()
11 | session.default_timeout = 60
12 | connection.register_connection("session", session=session, default=True)
13 |
14 |
15 | class Todos(Model):
16 | __keyspace__ = KEYSPACE
17 | __table_name__ = "todoitems"
18 | user_id = columns.Text(primary_key=True, required=True)
19 | item_id = columns.TimeUUID(
20 | primary_key=True, clustering_order="DESC", default=uuid.uuid1)
21 | url = columns.Text()
22 | title = columns.Text(required=True)
23 | completed = columns.Boolean(default=False)
24 | order = columns.Integer(db_field="offset")
25 |
26 |
27 | sync_table(Todos)
28 |
--------------------------------------------------------------------------------
/week4-api-microservices/slides/slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datastaxdevs/bootcamp-fullstack-apps-with-cassandra/737c17e0a618dd2b7bafb3700116a6b477203b01/week4-api-microservices/slides/slides.pdf
--------------------------------------------------------------------------------