Spring Boot, React.js & AWS S3 Full Stack Development

Spring Boot, React.js & AWS S3 Full Stack Development


Spring Boot, React.js & AWS S3 Full Stack Development

In this spring boot tutorial you’ll learn how to create a spring boot project for a full-stack application with React.js that enables users to upload files to Amazon S3 with ease. Follow along as we dive into the integration of React.js on the frontend and Spring Boot 3 on the backend to create a restful API that enabling file uploads.

By the end of this tutorial, you’ll have the knowledge to develop your own file uploading functionality in your next project, and take advantage of the power of AWS S3 for your application’s storage needs.

▷ Enrol for certificate - bit.ly/41PG7iZ
▷ Follow Me on LinkedIn - https://bit.ly/3Nqrpuy
▷ Join Amigoscode LinkedIn Group - https://bit.ly/44snIKX
▷ Join Amigoscode Discord - https://bit.ly/3Llkf7T
▷ Repo - https://bit.ly/41O3OYN

Don’t Forget to
===========================================
💯 Subscribe to Amigoscode - http://bit.ly/2HpF5V8
💯 Courses Available for free here - https://amigoscode.com/courses
💯 Join Private Facebook Group and Discord - https://amigoscode.com/p/join-community

🙊 Here are the goods for all my videos video 🙊

► Recommended Books
===========================================
- Clean Code - https://amzn.to/2UGDPlX
- HTTP: The Definitive Guide - https://amzn.to/2JDVi8s
- Clean Architecture - https://amzn.to/2xOBNXW

► Computer and Monitor
===========================================
- New Apple MacBook Pro - https://amzn.to/3464Mmn
- Dell 27 INCH Ultrasharp U2719D Monitor - https://amzn.to/2xM3nW1
- Double Arm Stand Desk Mount - https://amzn.to/3aYKKfs
- USB C Hub Multiport Adapter - https://amzn.to/2Jz7NlL

► Camera Gear
=============================================
- Sony ILCE7M3B Full Frame Mirrorless Camera - https://amzn.to/346QIJn
- Sigma 16 mm F1.4 DC DN - https://amzn.to/2wbic3Q
- Sigma 33B965 30 mm F1.4 DC DC - https://amzn.to/39G37Fd

► IDE \u0026 Tools I use for coding 💻 🎒
===========================================
- ITerm
- VsCode
- GoLand
- IntelliJ Ultimate
- Sublime

P.S
===========================================
💯 Don’t forget to subscribe | http://bit.ly/2HpF5V8
💯 Join Private Facebook Group and Discord - https://amigoscode.com/p/join-community
💯 Follow me on Instagram | http://bit.ly/2TSkA9w

❤️ Thanks for watching


Content

0 -> hey what's going on guys welcome to Amigoscode  in this spring boot tutorial I'm going to take you through  
7.38 -> the journey of learning how to implement the  functionality of storing files using spring  boot
14.88 -> React,js and AWS S3. I've done this video a couple  days ago and I decided to basically re-revamp and  
22.5 -> because it's part of the full stack professional  course which is over 60 hours and growing with  
28.86 -> new features that you guys have been requesting  so I decided to just revamp the video that I've  
36.66 -> done a couple years ago and also if you want  to gain a certificate on the website you can  
42.06 -> basically enroll and basically take this crash  course and gain a certificate and this course  
48.3 -> is Hands-On so get ready and clone the repo and  yeah I want you to learn something new from this  
56.52 -> video if you're new to this channel literally  just take one second and subscribe and also  
63.84 -> for all of you guys smash the like button come  on I'll give you one second that's it without  
70.44 -> further Ado let's go ahead and learn about spring  boot react AWS and S3 catch me on the next one
84.12 -> in here I've put this diagram together where  you can basically have an idea and see all the  
90.66 -> different services that you need within AWS  but basically right here this is our API that  
96.96 -> you basically have deployed successfully to an  ec2 instance backed by ECS now the API actually  
105.84 -> is running on this ec2 instance and we want to  upload pictures to a bucket so Amazon they have  
114.24 -> a service called S3 which basically allows you  to store files now before you can upload files  
121.8 -> you need to basically configure the row so the  role that is called AWS elastic Beanstalk EC2  
132.06 -> roll in my case to have the ability of accessing  this bucket in here if you don't have that then  
142.14 -> whenever this ec2 instance that has a row tries  to access the bucket IE to upload it will fail  
152.4 -> so we need to attach a row then we can use the SDK  by Amazon and I'm going to let you go and try and  
161.46 -> figure out which one to use but later I'll give  you the solution but basically you can use the S3  
167.34 -> client and what I want you to do in this exercise  is the ability of you having two implementations  
175.8 -> so one which basically connects to the real S3  bucket and then the other one that basically acts  
183.9 -> as an S3 backed by a folder under a path within EC2 your file system so in my case I'm going to put  
194.16 -> it under home a folder called dot Amigos code and  then S3 and then images and then user ID and then  
201.9 -> the image ID so this will be the idea and in here  this would be number three in fact right here  
211.02 -> and also what you need to do is to store  the fact that a customer has an image so  
217.86 -> that you can then later retrieve the image  of the bucket with the corresponding ID  
224.46 -> and here you see that we do have IntelliJ and  basically in here you should be able to run your  
230.82 -> code and what I really want to see is actually  an integration test that basically simulates all  
238.62 -> of this so adding to AWS so S3 but also to the  fake one in here and mainly you know when we are  
246.48 -> running integration tests we're not going to have  the ability of communicating with AWS services  
251.46 -> so that's why we do have this fake implementation  so that the integration tests do work when we use  
258.78 -> them within GitHub actions and on the front end in  here I've got basically a bunch of people in here  
266.64 -> so people are messing up with this application  at the moment but in here so if I click on update  
273 -> so here I've got this basically drag and drop  component where I can drag a picture in here  
278.46 -> or I can select so let me show you the drag  and drop feature so here I do have a couple  
283.8 -> of pictures and literally I can take any picture  so let's say Georgie so Georgian let's just take  
291.96 -> my picture in here and here I can drop the  picture and this will upload to the server  
299.58 -> and currently I don't have any loading and you  can see that basically took some time but it was  
306.54 -> actually uploading the picture uh but basically  if I search now for joji so G orgy is it Georgie  
315.42 -> G or G or G or G there we go so this is Georgie  right here and you can see my picture also if I  
326.16 -> click on update and here now you can see that  the picture is present in here and obviously I  
333.9 -> can basically upload the picture again so let me  just now pull a female for example and just bear  
340.5 -> in mind that as I said so there's no loading  component at the moment but you can add that  
344.46 -> yourself so if I drag the picture so at this point  it's actually loading and this time it was faster  
349.8 -> so if I search for Gog again so command f so G or  G or G and you can see that this is the picture  
359.58 -> now click on update and it's working beautifully  awesome let's learn how to implement all of this
370.68 -> so for this course I want to be using IntelliJ  as the IDE of choice and the IntelliJ they've  
376.56 -> just launched their brand new theme which  currently it's in beta mode and maybe by  
381.6 -> the time that you watch this video it might not  be in beta but it really doesn't matter if I use  
387.54 -> the new UI theme or the old UI theme because  it's just coding okay so when I run some code  
395.04 -> is going to be the exact same place so  all you have to do is just look for the  
398.52 -> play button and it's basically the same  place it's quite easy for you to see then  
404.64 -> the other thing is I'm doing a giveaway and I'm  giving you the IntelliJ license so the ultimate  
413.1 -> for three months I can't even say three months  so for three months right and all you have to do  
420.06 -> is follow me on my LinkedIn profile also there's  a brand new group which you will basically find  
428.1 -> a link and the description of this video within  LinkedIn so we have a LinkedIn group now and also  
434.76 -> join Discord because that's where if you have  any questions about the course you should post  
441.6 -> um your questions okay so this code is a very  active community and you should be part of it so  
447.3 -> join all those three uh so follow me I'm not join  but follow me join the LinkedIn group and also  
454.86 -> Discord and you should get your license cool this  is pretty much it I'm so excited let's get started
468.48 -> if you want to follow and code along  with me which I think is the best  
473.46 -> way of you to learn all of the stuff that  I'm about to teach you go ahead and clone  
478.56 -> the repository which you can find the  link and the description of this video  
483.6 -> So within the repository click on code and then  in here you are able to basically clone using SSH  
490.44 -> you can see some description about basically this  is part of the curriculum which is over 50 hours  
497.28 -> and we are adding more content to it so also you  can look into the commits in here which I'm going  
504.48 -> to show you which one you have to commit in order  to follow along so go ahead and pretty much just  
511.02 -> clone so click on code grab this link and then  open up your terminal so in here I've got my  
518.34 -> terminal open and you can literally clone this to  anywhere within your file system so if I say PWD  
525.42 -> you can see that this is uses for slash Amigos  code and right now let me just go to desktop  
531.96 -> so CD and then desktop and in here I'm going to  say git and then clone and then paste the link  
539.04 -> awesome so now it's actually cloning and there  we go next let's open up this repo with IntelliJ
553.26 -> for this course I'm going to use IntelliJ ultimate  and it's by far the best IDE for Java development  
560.34 -> and also for full stack it's amazing so luckily  for you I've got a coupon code for three months  
567.72 -> in which you can basically use and have access to  all the features so here if you navigate to this  
573 -> website which I'm going to leave the link and  the description of this video and if you click  
577.38 -> on download you'll see that IntelliJ basically  they have two versions they have the community  
581.64 -> as well as the ultimate so this one is a paid  version which I'm going to give you access for  
588 -> three months as I said now the best way for  installing IntelliJ is not directly and you  
595.74 -> should do it through so if we click on developer  tools and in here you should see the toolbox app  
602.46 -> so basically this is the best way for you  to manage all of your jetbrains Ides so  
608.22 -> this basically allows you to upgrade easily  install rollback and downgrade and all that  
613.68 -> good stuff so basically go and install the  toolbox app and then you'll have access to  
620.7 -> and then you'll be able to install IntelliJ  let me show you so in here I already have  
626.64 -> the toolbox app which is available in here so  if I click on toolbox you can see that this  
632.4 -> opens up the toolbox and if I click on tools  you can see that I do have IntelliJ Community  
638.46 -> I've got idea and there's updates which I need  to basically do and you can see all the other  
644.64 -> ones in here but the one I wanted to install  is this one in here and I'm going to leave  
650.34 -> the instructions on how to get the three months  license next let's go ahead and open up IntelliJ
661.32 -> all right so in here if I open up IntelliJ you  should be presented with a screen that looks  
667.32 -> like this so let's open up our project so here  I'm going to click on open or if you want you  
675.48 -> can get from VCS so you just paste the GitHub  link and basically just clone the repo also if  
682.62 -> you have the exact same version you can enable  the brand new UI which is I think in build beta  
689.52 -> mode which I'm not going to use so I just want  to make sure that basically all the recordings  
694.14 -> are with the same IDE but if you want to use  their brand new UI feel free to do so it looks  
701.76 -> pretty good actually so here I'm going to click  on open and then within my desktop this is where  
707.1 -> I've got the folder so open the folder and all  I want you to do is to open the root so this  
714.66 -> is a mono repo where we have the front end the  back end and whatnot so just open there we go  
721.2 -> and you can see now there's a few things about  what's new about IntelliJ so I've just updated  
728.1 -> and if I close this there's also the readme I'm  going to close this and I'm going to basically  
734.64 -> load this because you found the maven build  script there we go so just give it a second  
743.7 -> and I'm going to cancel this plugin here and  there we go so if you manage to get this right  
750.78 -> here where you see the folder in here and it  looks like this and if you expand you should  
756.3 -> see CI GitHub git ignore backend front end within  the front end we have angular react so if you see  
764.52 -> all of this in here you've successfully managed  to open the project with IntelliJ cool the next  
773.52 -> thing that I want you to do is if you open up git  in here you should see that there's basically all  
780.96 -> of these commits in here and what I want you  to do is to check out the point before the  
788.58 -> file upload so here I think so this is the readme  stuff that I've done and then this is the react  
798.12 -> and then in here so basically I think it's this  one right here so basically what I want to do at  
806.58 -> this point so I want to check out the code before  I implement the file uploads so you see S3 file  
815.28 -> uploads the commit before it no this one because  this one is a branch but before it enroll to  
822.18 -> enroll so basically two L's to one L so basically  right click and then what I want to do is to check  
829.98 -> out revision so basically we're going to check  out to this point so check out and there we go  
840.06 -> so I'm also going to leave the command so in  case you want to check out using the terminal  
846.54 -> or command line what you do is so here I'm going  to right click and we should be able to copy the  
854.4 -> revision number just like that and if I hide this  and in here so basically it's just downloading a  
863.82 -> few things let this finish and you can see  the revision in here actually so the reason  
870.78 -> why I'm doing this is so that you can follow  along awesome so here we can open the terminal  
877.32 -> and you can see that this is the revision  now if I say git check out and then Main  
884.76 -> you can see that I went back from this revision  to main right now I can say git checkout and then  
893.1 -> paste the revision so basically this long number  in here press enter so this is the exact same  
900.54 -> thing have a look now the head is at enroll to  enroll so I'm going to leave this command as well  
907.02 -> so that if you want to do it this way you can do  it but but this will be the starting point for us
919.14 -> in order to successfully run the application  you need to install Docker and basically Docker  
924.66 -> is just a fancy way of you basically running  anything that you want locally without having to  
931.26 -> do any setup whatsoever so if you want to learn  more about Docker I have a course on Docker and  
936.78 -> Docker is a must these days if you are serious  about becoming a software engineer or if you're  
943.56 -> a software engineer and you don't know much about  Docker then you must know about Docker right now  
950.4 -> so go and install Docker and once Docker is  installed you should see something called  
956.82 -> Docker desktop so in here if I click on  this button in here so open the dashboard  
964.5 -> and you should see something like this so  let's take this command in here so if this  
971.7 -> is the first time that you run Docker just take  this right here so this command copy and open up  
978.18 -> your terminal and what we're going to do is just  paste that command and this will verify that we  
983.82 -> have Docker installed so basically it's just going  to run a hello world or getting started container  
991.32 -> you can see that it says enable to find  it's going to do something like this  
996.72 -> and it's going to basically run and then finish  so if the command run and executed successfully  
1004.58 -> what I want to do is open up Docker desktop  and you should see this right here which is  
1011.36 -> a brand new container cool and this guy  here is running on Port 80. and if you  
1019.58 -> want to see the exact same details through the  terminal you could just type Docker and then PS  
1026.48 -> so here basically is the same information  so you have one container right here so  
1032.24 -> basically port 80. on the host mapping to  Port 80 inside of the container now what  
1038.54 -> I want to do is I want you to open your  web browser and together let's type local  
1045.86 -> and then host literally just localhost press enter  and you should get this right here up and running  
1055.94 -> so if you manage to get this page right here it  means that everything it's working as expected  
1063.26 -> now let me destroy this container so in here back  to Docker desktop we can basically delete the  
1070.52 -> container through here or through the terminal by  saying Docker RM and then let's say Dash f 4 so we  
1079.82 -> don't have to stop the container get the container  ID and then paste and then enter and you should  
1087.74 -> get the ID back and now within Docker desktop no  containers are running and if I try to access the  
1096.02 -> same page so this one here before so if I reload  you can see that the site cannot be reached  
1103.7 -> cool so if you've done all of this congratulations  you are on your way in terms of learning Docker  
1109.94 -> next let's go ahead and get the database I've  been running for our application using docker
1120.56 -> cool in order to get the database up and running  for this course we're going to use Docker as it's  
1127.04 -> the world most advanced open source relational  database and it's quite popular and it's one  
1133.7 -> that I recommend on my courses so let's go ahead  and get this database up and running with Docker  
1141.68 -> So within IntelliJ if I just hide this you should  see that there's a file called dockercompose.yaml  
1149.06 -> and in this file this is the ammo definition for  Kepler containers so here I've got one called DB  
1156.8 -> and this is for the database then I also have  another one for the API so this is the API that  
1163.04 -> we build in the course and then we containerize  and the idea is that we can just use this Docker  
1170.36 -> compose file and then get the entire stack up and  running also we have the front end with react here  
1177.44 -> as well cool and if you want to learn more about  all of these as I said check out the docker course  
1182.48 -> where I teach all of this so for now what I'm  going to do and this is very important let's get  
1188.54 -> rid of the API in here so this service so I'm  going to collapse this as well as react so we  
1195.14 -> don't need none of this and I don't want this to  cause us any issues so I just want us to be able  
1201.44 -> to have the database I've been running because  this is what our spring boot application will need  
1206.48 -> when we run it locally cool so now make sure that  you have this exact same file as is and I'm going  
1214.4 -> to leave this in the description of this video so  that you could just copy and paste but one thing  
1219.56 -> to bear in mind is have a look The Amigos code is  the user and the password and here is password so  
1225.32 -> this is what this springboard application uses to  connect to this database cool next let's open up  
1231.2 -> the terminal and within the terminal what we're  going to do is we're going to CD into the full  
1237.44 -> stack folder so here I'm within the desktop  so CD full stack professional and now if I  
1244.4 -> type LS you should see that we have the docker  composer yaml if I say cat Docker composer yaml  
1255.26 -> you can see that this is the file that I've just  showed you with one service which is the database  
1261.92 -> awesome now what I want to do is simply to  say docker compose and then up Dash and then d  
1273.38 -> so this is Docker and then within Docker  there's another compose tool and basically  
1280.52 -> allows us to run containers based of the yaml  definition and D is for detached mode press enter  
1287.78 -> and you can see that for me this was super  quick but for you maybe if you're running  
1292.46 -> this first time it should take some time to pull  the images or to pull this postgres image in fact  
1301.34 -> nice now go ahead and type docker and then  PS if you type Docker PS and you have one  
1311.96 -> container is fine right and the container is up  and running but if you use Docker before and you  
1317.3 -> have multiple containers look for the one called  in here postgres so names post and then grass  
1326.12 -> also there's this nice environment variable  so here I think it's format so I think let me  
1333.86 -> just say export and then format which I'm going to  leave in the description of this video press that  
1339.74 -> and then I can say Docker PS dash dash format and  now this gives me the output formatted nicely like  
1350.48 -> this instead of like this and here you can see  the ID the name the image the port So currently  
1358.16 -> it's localhost 5332 mapping to 5432 inside of the  container the command created and the status which  
1369.86 -> basically up about a minute ago now what I want  you to do is let's take either the name or the ID  
1377.36 -> and say Docker logs and take the name or the  ID press enter and in here you should see this  
1389.72 -> exact same output that says database is ready to  accept connections awesome if you've managed to  
1398 -> get this far congratulations if not let us know  within this code otherwise next let's go inside  
1404.6 -> of this container and create a database called  customer which our backend needs in order to run
1418.34 -> within IntelliJ if I close the  docker compose yaml for now  
1423.74 -> and let us open the backend folder SRC main Java  and here you have the main class so if you try  
1434.84 -> to run this main class in here or you can run it  through here or right click run this should fail  
1443.48 -> in here there we go and it fails because  the database customer does not exist  
1450.62 -> so let's create that within our database so  you've got two options you can connect using  
1457.1 -> the database client in here with IntelliJ or  through the terminal so let me do it through the  
1463.46 -> terminal So within the terminal if I type Docker  PS you can see that we have one container which  
1470.36 -> is running and this is the database so let's take  the database name or ID say docker exec Dash it  
1481.1 -> just like this paste the name or the ID for our  container and then say sh now we are within this  
1491.6 -> container and this basically is just a Linux  box if I type LS you can see the Linux file  
1496.94 -> structure so what we're going to do is type psql  so this is the official CLI client for postgres  
1504.8 -> here say Dash capital u Amigos code so this is  the user and also let's connect to so say Dash D  
1515 -> and by default we should have a database called  post and then Grace press enter and you can see  
1523.34 -> that we are inside at this point if I press  Ctrl L it just makes some room for us there  
1530.24 -> and if I type backslash L you can see that this  lists the databases and currently there's four  
1537.92 -> so Amigos code postgres template 0 and template  1. so what we're going to do is let's just say  
1545.48 -> create and then data base and in here we're  going to create a database called customer  
1553.82 -> and then make sure that you have a semicolon enter  and if you have the exact same output so if this  
1561.2 -> comes back create database it means that it was  successfully created and also if I type backslash  
1569.42 -> l once more clear the screen press enter now you  can see that we have the customer database inside  
1578.12 -> so let's basically connect to customer so say  backslash C and then customer and now if I type  
1588.02 -> backslash and then D enter there's no relations  let's open up IntelliJ and if we try to run the  
1597.86 -> application once more so this time it should  just work there we go and we have a user in here  
1607.34 -> so insert into customer age email blah blah blah  blah blah values and the application is up and  
1616.88 -> running awesome next let's go back to the database  and if I type backslash and then D once more  
1624.74 -> now you can see that we have few relations we  have the table called customer the sequence and  
1630.98 -> Flyway schema history as well as a table so if I  say select and Then star from and then customer  
1641 -> if I press enter so make sure you have  semicolon there you can see that we have this  
1647 -> customer right here now let me say backslash  t and then run the exact same command again  
1655.1 -> or sorry not t so let me just toggle  it off and I think it's backslash X  
1661.82 -> yes expand the display on so let me just run the  exact same command so select start from customer  
1669.38 -> and you can see how the data now comes this  way and this is our customer id1 that's the  
1676.46 -> name the password obviously in here is  encoded and gender mail and the age 98.  
1685.7 -> so if you managed to get this far congratulations  next let me go ahead and press Ctrl D to come out  
1694.28 -> of psql and then Ctrl D once more to come  out of the container and we are good to  
1701 -> go if you've managed to get the back end  up running congratulations otherwise let  
1706.16 -> me know if you are facing any issues so that  you can follow along catch me on the next one
1716.48 -> in order to get the front-end up and running  either react or angular what we need to do is to  
1722.72 -> install node.js so this is very important in order  to run our front end locally so download either  
1731.9 -> the long term support or the current it doesn't  matter because it should just work once you have  
1738.08 -> node installed open up the terminal and within the  terminal so if I clear the screen in here Ctrl l  
1745.52 -> I'm going to say CD and then navigate to  Front End and let's first do react there we go  
1756.14 -> and in here I'm going to type npm so just type  npm and you should see that this will come back  
1763.64 -> and say hey you want to do something these are the  usages right so it means that we have successfully  
1770.36 -> installed node.js and when you install node.js it  comes with npm which is the package manager so now  
1778.64 -> what we're going to do is say npm and then I and  in fact before I do that if I type LS have a look  
1787.34 -> so these are the files and folders We have but  when we type npm I or install is the same thing  
1796.46 -> this will go and download all dependencies  and you can see that added 269 packages  
1803.3 -> so here let's just type LS once more and now you  can see that we have node modules let me clear the  
1810.68 -> screen and now to run the react front end just  type npm and then run and then death awesome so  
1820.22 -> you can see that it says this is actually running  on localhost 5173 so let's just take this URL  
1828.8 -> and open up Chrome new tab paste URL press enter  and you should see this beautiful UI awesome if  
1840.5 -> you want to log in to grab the credentials open up  IntelliJ and remember when we started the back end  
1846.26 -> you should see the logs this email so just take  the email go back and then paste that and for the  
1854.18 -> password is going to be password and then login  and you can see that it works click on customers  
1863.18 -> and you should see that we have one customer  in here and we can update we can delete the  
1869.78 -> customer if we want and also let's try to add  a new customer so here let's just say Jean
1878.54 -> let's say she's 22 password is going  to be password and then gender female  
1890.24 -> submit you can see that she's added in here and  let's try to login with Jean sign out this will  
1900.86 -> be Jean at amigosco.com the password is password  login and now we are signed in with Jean customers  
1911.48 -> and we can see everyone again awesome if you've  managed to do all of this congratulations you  
1918.62 -> are on your way in terms of building the  functionality to upload pictures with AWS
1930.2 -> cool let's begin our journey in terms of building  all of this the very first place that I always  
1936.86 -> start when I have to basically use an SDK or an  API or basically Implement literally any feature  
1946.64 -> is by looking at the documentation and then take  it from there so in here I'm within the AWS SDK  
1954.68 -> for Java documentation so this is the official  documentation from AWS and in here basically we  
1962.96 -> learn how to integrate AWS services with Java so  you can find the link on the description of this  
1971.72 -> video for this documentation but here I know that  for a fact that you know version one is actually  
1978.56 -> deprecated and there's a new version which is two  there's also a migration guide and in here so we  
1985.88 -> have the API reference and here we have the  developer guide so let's look into developer  
1992.72 -> guide and this should gives us more or less an  idea of how to get up and running so on the left  
1999.74 -> you can see that we have you know get started  tutorial some information about the SDK and  
2007.3 -> setup SDK features security documentation history  and whatnot so let's click on get started tutorial  
2015.22 -> and here you can basically follow this tutorial  if you want to get up and running with this SDK  
2021.4 -> but in here so basically if I scroll down this  is a maven project you can see the palm.xml and  
2029.62 -> in here you can see that they have the dependency  and then basically they use the SDK like so  
2037.36 -> and um yeah so also under setup in here they also  have you know a more detailed guide I think with  
2046.42 -> Maven and possibly Gradle as well and how  to migrate from version 1 to version two  
2052.96 -> so on and so forth so in here so let's basically  click on build steps so I want to set up with  
2061.84 -> Apache maven and actually let's look into  right so this actually it's using the SDK so  
2070.66 -> in here what I really want to take from is the  dependency so if I scroll down I can see have  
2077.62 -> a look declare the SDK as a dependency so here  this is the version in here and if I scroll down  
2086.8 -> so this is the dependency management which we  are not using but instead we're going to take  
2094 -> the dependency right here so the S3 dependency  like so so let's basically command C on this guy  
2103.42 -> and then open up IntelliJ and within IntelliJ  open up palm.xml and in healing for this full  
2110.92 -> screen and under dependencies in here I'm going  to basically add it as the last one now here we  
2119.32 -> also have to add the version so here version and  the version as it stands I'm going to use 2 20 26.  
2129.04 -> and if I go back in here have a look 220 I think  there's a newer version actually as I'm speaking  
2136.9 -> but basically I would say try and use the same  version as I have or probably if this is not  
2145.96 -> three so basically three which means the major  version upgrade then everything should just work  
2152.38 -> cool let me go back to IntelliJ and you  could take this right here so this version  
2158.56 -> as a property but I'm going to leave it as is  and let me just click on load maybe changes  
2166 -> and this is pretty much it next let's  go ahead and learn how to use this SDK
2180.46 -> cool we have the maven dependency and let me  collapse setup in here use the SDK so if I click  
2189.22 -> on it you can see that they give us basically  an example on how to use it but one thing that  
2197.26 -> we need to make sure that we have first is here  if I click on provide temporary credentials so  
2203.86 -> before making a request to AWS we need temporary  credentials so that we can use these Services  
2211.36 -> provided by AWS here we have temporary credentials  so if I click on it they basically show us what  
2218.8 -> we need to do then we have default credential  provided chain so this is when you basically  
2226.42 -> are initializing this service within Java then  this is where the credentials are retrieved from  
2235.06 -> so first is from java properties then environment  variables web identity token shared credentials  
2243.94 -> ECS container and then here easy to instance imbro  which later you'll see how we're going to use this  
2253.54 -> but what we're going to first use is temporary  credentials so here if I click on it so basically  
2261.94 -> what we're going to do is we're going to retrieve  the credentials from AWS console and then we're  
2268.66 -> going to store them in a location called here so  under home dot AWS and then credentials and this  
2278.56 -> is mainly for local development right then we're  going to add the access key ID the secret access  
2285.64 -> and I think for us this should be more than enough  and here you can follow you know details on how to  
2293.02 -> do it but don't worry I'm going to show you how  to do this so let's go ahead together and open  
2299.86 -> up the AWS console and within the console navigate  to your username so in here Amigos code in my case  
2308.32 -> then navigate to security credentials and  within this page in here you should see  
2314.68 -> access management on your left click on users and  in here if you remember correctly before we added  
2324.22 -> Amigos code gitup actions so now what we're  going to do is we are going to add a new user  
2331.54 -> and here I'm going to name this user as  Amigos code and here I'm not going to  
2339.58 -> provide access to the console so this will  be programmatic access only click on next  
2346.78 -> and for the user group what you could do is you  could say right so this user is only allowed to  
2354.7 -> use the S3 service for example but in my case  in here I'm going to use the admin so I want to  
2364.42 -> give full control to all services within AWS to  Amigos code so that user will have full control  
2374.14 -> and also you can set permission boundaries but  we don't want to do that and if you don't see  
2379.84 -> admin in here you can create a group  so let's just see if I create a group  
2385.96 -> and here you can see administrator here provides  full access so basically you then select admin  
2395.68 -> and then just say admin in here and you should  have the exact same group as I do so this is  
2403.18 -> the admin in here but let me just show you for  example S3 so in here so you can see that these  
2410.98 -> are so here S3 full access maybe you just want to  limit the user to have access to S3 and that's it  
2419.56 -> or S3 read only that's it right so in my case in  here I'm going to give full access as I said let  
2427.66 -> me just collapse that and select admin in here  and let's click on next and you get a summary  
2436.54 -> in here so the username is Amigos code and the  group is admin in here no tags create the user  
2446.98 -> awesome so now that we have the user next what we  have to do is issue the credentials for this user
2460.54 -> previously when you created the user you would  get issued the credentials but now we have to  
2467.38 -> do this on a separate step so click on the user  that you just created so in my case Amigos code  
2473.5 -> and then what you need to do is under security  credentials click on it and in here if I scroll  
2482.38 -> down we should have access keys so access keys to  send programmatic calls to AWS from the AWS CLI  
2494.86 -> tools SDK or API calls so a maximum of two  keys active or inactive at a time so let's  
2506.44 -> create the access key and in here what I want  to be able to is to access through the CLI in  
2515.68 -> here right so there's no local code there's  no application running on compute service at  
2523.24 -> this point so we're not going to do this and you  shouldn't really do this actually you should use  
2528.52 -> I am rolls which I will show you later and in  here so the application is not running outside  
2535.42 -> AWS so in here what I want is local code and you  plan to use this access key to enable application  
2543.04 -> code in local development environment to access  your AWS account so this is exactly what we want  
2548.38 -> and in here so let's just basically say I  understand the above recommendation and click next  
2558.04 -> in here if you want you can basically add a  tag which I'm not going to and then generate  
2565.72 -> access key cool at this point you see that we  have the access key as well as secret access  
2574 -> key and we have some best practices on how  to access the key itself so never store the  
2581.5 -> key in play text disable access when no longer  needed enable list privilege permissions which  
2588.28 -> we haven't done we just you know said that the  role itself or the user is an administrator  
2595.78 -> and rotate access Keys often so in here what we  need to do next is take the axis key as well as  
2604.66 -> secret key and then store them within our local  machine and I'm going to show you where next
2616.78 -> so in order to store these values the access  key as well as the secret access key if I go  
2623.98 -> to the documentation in here so under use the  SDK use temporary credentials there should be  
2631.9 -> a section here so basically set up a local  credentials file for temporary credentials  
2637.78 -> so here basically what we have to do is  we have to get something like this under  
2644.5 -> the home directory dot AWS and then a file  called credentials so if I open up my terminal  
2654.34 -> and within my terminal in here just basically  type CD and then tilde or just CD and this if  
2661.9 -> I say PWD you can see that this is uses and  then forward slash amidoscope now under it  
2668.5 -> so if you don't have a folder called AWS just  go ahead and create a folder like so so say make  
2677.02 -> there dot AWS okay so I already have this folder  so I'm going to say CD to change directory to AWS  
2687.76 -> and in here if I type LS you can see that  we have credentials so this is a file now  
2696.1 -> what I'm going to do is I'm going to  open this with VI and then credentials  
2703.18 -> press enter and in here I do have one profile  which is the default so basically have this  
2710.74 -> so open square brackets say default close square  brackets and then have AWS access key ID and then  
2719.74 -> this should be the ID and then do the same for AWS  secret access key and then the access key that was  
2728.2 -> given to you so what I'm going to do is I'm going  to basically press I in here and I'm going to  
2735.28 -> press or actually Escape I'm going to press J to  go down W to word and then press basically D and  
2745.6 -> then W to delete basically the word and press I  now in here I'm going to paste the access key ID  
2754.42 -> so back to the console the access key so this  guy here copy and then here I'm gonna paste I'm  
2764.56 -> going to press Escape J and here I'm going to go  back a word and then press d w and basically it  
2774.16 -> deletes the secret access key I for insert and  let's basically paste the secret access key now  
2785.38 -> here I'm going to show you the value and that's  because after this video I'm going to regenerate  
2792.1 -> the access key as well as the secret because  otherwise anyone with these credentials can  
2799.12 -> have full control or full access on my account and  I don't want that to happen so these values here  
2806.38 -> they should be kept secret so never show them to  no one so here I'm going to copy and then go back  
2815.38 -> and then paste and you can find the contents  for this file under the description of this  
2821.8 -> video so that you can just copy and paste  but let's press Escape and then colon and  
2829.72 -> then WQ so we want to write and quit cool so if  I press cool if I type cat and then credentials  
2841.66 -> and you can see that these are the credentials  that we just copy and paste it and this should  
2849.52 -> be it if you have any questions drop me a  message otherwise catch me on the next one
2860.44 -> cool back to the documentation in here we have the  credentials out of the way now SDK features so I'm  
2868.96 -> not going to show you basically the features and  here work with AWS Services if I open this app in  
2877 -> here have a look we've got a bunch of services  and the one that we are interested is Amazon  
2885.22 -> simple storage or simply S3 so you can also work  with Dynamo ec2 I am Athena Cognito Lambda Amazon  
2896.8 -> poly sqs Amazon translate and basically all of  these all the services in here so the one that  
2907.6 -> we are interested is the S3 simple storage service  so basically this section provides a guide on how  
2916.6 -> to get up and running with S3 but let me just  show you so S3 if you don't know much about S3  
2924.82 -> but S3 basically object storage built to retrieve  any amount of data from anywhere now here so five  
2934.36 -> gigs of standard storage for 12 months with the  AWS free tier which is way more than enough for  
2941.86 -> what we need because we're just going to store  pictures and here you can scale storage resources  
2948.1 -> you can store across storage classes you can  protect your data and it's easy to manage data  
2954.82 -> at any scale and more so here they've got a  diagram on how it works which I'm going to let  
2961.36 -> you basically go through it but literally  analytics data log files application data  
2968.56 -> videos pictures backup and archival literally you  name it you can store anything within Amazon S3  
2978.76 -> so basically all you need is just a bucket  so they call it bucket where you can just put  
2985.24 -> your files in it or your objects so you can  see like the use cases but it's very popular  
2992.98 -> and it's one of the services that you should  know how to use within AWS because now we  
3000.24 -> store data more than ever before next  let's go ahead and learn how to have  
3007.86 -> the configuration for our S3 client that will  enable us to use Amazon S3 programmatically
3022.26 -> cool within the documentation working with Amazon  S3 in here they give us some code snippet on how  
3029.28 -> to get up and running with S3 so let's together  take this piece of code and open up IntelliJ  
3038.46 -> and within IntelliJ let's open a project and  within the backend folder let's open up the  
3045.9 -> main Java and in here under the root package  let's create a new and then class and here  
3055.2 -> we're going to say S3 Dot so this is the name of  the package and the name of the file will be S3  
3064.92 -> and then config just like that so you can  create a package like this so press enter  
3072.66 -> and you can see that we have the package in  here and the class called S3 and then config  
3078.36 -> now this class in here so let's just basically  annotate this with ADD and then configuration  
3084.78 -> and it's going to serve as a means for us to  create the client so here let's say public  
3094.5 -> and then S three so S3 and then client not  configure S3 client just like this from  
3105.9 -> software Amazon AWS SDK Services S3 S3 client  so this is the interface in here and I'm going  
3116.16 -> to say basically S3 client and inside here I  want to paste the code that I've just copied so  
3125.28 -> just like this now I don't think that we need the  end point override in here so we do need that and  
3133.56 -> also let's remove the force path style so I think  all we need is the client provide the region and  
3144.36 -> then say build and then we have the client now the  region this is very important so whatever region  
3151.32 -> Which is closest to you and where you want your  bucket to reside just choose the right region so  
3158.82 -> in my case let me just import class and this will  be so basically EU and then I think it's uh EU  
3172.32 -> and then underscore West one now this right here  if I press command and then navigate into it  
3180.48 -> so this is just a string like so right so  what I'm going to do in fact is I'm going  
3187.92 -> to take this string close the region class and  in here I'm going to have private and then I  
3195.96 -> want to say string and then AWS and then region  and don't say final there say at and then value  
3204.72 -> and within the value in here so have dollar sign  and then curly brackets and AWS and then Dot and  
3214.86 -> then region so the reason why I'm doing this  is so that you can basically just change the  
3220.98 -> region from within the configuration file so  here then we just say region and then value  
3228.36 -> or actually region of and then the string  is AWS and then region cool so now we need  
3235.74 -> to Define this guy in here so let's just open  a project and within project open resources  
3242.22 -> application.yaml and then literally anywhere so  here I'm just going to do it here so AWS colon  
3251.16 -> and then inside I'm going to say region colon and  then paste the string so EU West one so choose the  
3260.58 -> right region for your application now back to the  config so in here we are done and dusted with the  
3269.64 -> region the last thing that we have to do is return  the client just like that and we're good to go  
3277.14 -> finally let's annotate this with ADD and then Bean  just like that and now we have the client in here  
3285.96 -> later we're going to do some extra work in  here because we need a second implementation  
3291.66 -> that will serve for basically running the  application without has having to connect to  
3298.92 -> S3 directly so maybe we don't want to  use the credentials to AWS and in fact  
3305.64 -> we shouldn't have those credentials locally  so we're going to have a fake implementation  
3311.22 -> that will store files to our local file  system and also it will be used for testing  
3318.96 -> for now this is okay and later we will change this  this is pretty much it catch me on the next one
3332.04 -> now that we have S3 config let's together  create the S3 and then service so here I'm  
3339.06 -> going to say S3 and then service and this  class right here so we need to annotate  
3348.84 -> this with ADD and then service and this class  will have two methods you will have a method to  
3356.7 -> upload or to basically store objects and want to  download objects so let's together here basically  
3368.88 -> say that we want to have the clients so the  client now allows us to interact with S3 so  
3376.56 -> private final S3 and then client that we've just  configured and let's add this to Constructor and  
3385.86 -> now in here we can basically have a method to  put or to store objects to a specified bucket  
3394.68 -> within the documentation for S3 in here if  I scroll down they have topics on buckets  
3401.88 -> operations and an object operation so here you can  create a bucket so through Java code in here and  
3410.76 -> basically what you do is just this right but  we're not going to do this because you should  
3415.8 -> never create buckets through code and you should  have a team or maybe the infrastructure team the  
3424.14 -> devops team manage the infrastructure for you  I.E creating those resources through code ie  
3433.8 -> infrastructure as code with something like  terraform or palumi or cloud formation so  
3442.68 -> in our case let's look into object operations and  I'll show you how to create the packet in a second  
3448.62 -> but in here upload an object so here they give  you the actual code on how to upload an object so  
3456.6 -> here so we have the bucket then all you do is you  just have a put request and job done so what we're  
3465.3 -> going to do is let's take this go back and in here  let's have a method so I'm going to say public
3476.88 -> and then void and then put object and we're going  to fill in these in a second but so here let's  
3486.48 -> just paste the code let me put this full screen  let's import put object request and here we have  
3494.46 -> to pass the bucket name as well as the key so  these will come from so if I extract this to  
3502.5 -> a parameter so that will be the bucket  name and the key will also be coming from  
3509.76 -> the parameter just like that and what we  need to do in order to store to the bucket  
3517.38 -> is invoke the S3 client Dot and then put object  and then pass the object and and request in here  
3529.68 -> and more important the actual data so what we  want to store so what we're going to store is  
3536.7 -> the request body so here just say request body  and then from bytes and then the actual bytes  
3545.88 -> right or you could just say the file  for example here right as a byte array  
3551.94 -> so this guy here let's extract this to  a variable and this is pretty much it  
3560.76 -> so if you see that this is quite easy so we have  this method that allows us to store files to a  
3571.14 -> specific bucket with a given key and the file  in here which is a byte array cool next let's  
3581.4 -> implement the download functionality which  basically is just getting the byte array back
3593.1 -> so in here I'm within the official documentation  for S3 and basically this is what we've just done  
3600.54 -> with put now what I want to do is to have the  ability of and also you can upload in Parts using  
3609.12 -> multi-part upload which we don't need so usually  you do that for large files so here download  
3616.86 -> object have a look it's so simple and all you need  is basically just this right so let's just take  
3626.1 -> literally everything and then within IntelliJ  let's have the method here so I'm going to say  
3632.88 -> public and then here this will be byte so this is  what we get back and right here so we store the  
3641.22 -> file and we get it back right as a byte array  so here I'm going to say get and then object  
3649.98 -> or you could even say download the file but let's  just say get object and here we need to pass d  
3657.78 -> uh actually let's just use IntelliJ to generate  those so paste the code in here import class and  
3667.26 -> the bucket name here I'm going to press option  command and then P for parameter the same for key  
3675.66 -> there we go and in here so instead of S3 this  will be S3 client or we could even just say  
3684.72 -> S3 actually it's a better name right so S3  just like that so S3 S 3 S3 I could use a  
3699.06 -> a refactoring but that's fine so S3  get object and this is it right now  
3707.22 -> what I want to do actually so if you look  into the return type for this this is a  
3715.32 -> response input stream so I'm going to say  response right so response or res in here  
3723.66 -> from the response we can actually get the  bytes right so here we just say object  
3732.72 -> so here we just say risk so here we just say  res Dot and then have a look read all bytes so  
3741.96 -> this in here we need to basically encapsulate  within try catch so here we have the bytes  
3749.34 -> so here let's just surround this with try and then  catch and basically in case that there's nothing  
3756.54 -> there then it just throws an exception right so  throw in the new runtime exception and then the  
3763.56 -> exception in here now obviously if you want you  can add some logging in here to know exactly which  
3771.12 -> bucket and what key that you basically failed to  look at but for our case I'm just going to leave  
3778.74 -> this as is and that's it so now we can say return  and then bytes or if you prefer we can inline this  
3789.54 -> just like that which looks much better and this  is the implementation tool getting an object  
3798.6 -> if you have any questions drop me a  message otherwise catch me on the next one
3808.2 -> cool before we write any more code what I want  to do is I want to make sure that this indeed  
3814.2 -> does work so in order for us to test this what we  need to do first is to write some code that uses  
3822.54 -> these two methods but also create the bucket  itself so let's create a bucket So within AWS  
3830.1 -> console go to the main page in here and what I  want you to do is search for s and then three  
3840.9 -> and here scalable storage in the cloud also  added to favorites and now it's right in here  
3849.96 -> so click on it and in here you can see that I do  have a couple of buckets in here so don't worry  
3857.76 -> too much about these buckets in here but what we  want to do is to create a brand new bucket so just  
3864.66 -> click on create bucket and if I put this bigger so  in here so bucket name in here just make sure that  
3875.52 -> you type anything so in my case let's just say FS  for full stack Dash and then Amigos and then code
3887.52 -> Dash and then customer right so basically  this is mainly for customers and here let's  
3895.08 -> just say test maybe you want to have one for  a different environment so maybe development  
3901.92 -> staging production so let's just basically keep  this name as is also keep note of this name so  
3909.18 -> I'm just going to copy and in here so AWS region  so just make sure you select a region which is  
3917.22 -> the one where you are deploying your services so  in my case EU Island IE EU West one and I want  
3926.46 -> to leave everything as default no need to change  anything and right at the bottom create a bucket  
3935.52 -> cool now in here we should see the bucket so  where it is so here FS Amigos code customer  
3944.04 -> test so FS for full stack if I click on it you can  see that there are no objects and obviously we can  
3952.5 -> upload the files manually if we want to but I'm  going to show you through code in just a second  
3960.96 -> cool next let's write some code to test  that we can indeed upload files to S3
3974.76 -> okie dokie so we have the S3 bucket in here and  which is this one actually and uh basically what  
3985.44 -> we want to do is within IntelliJ we want to write  some code that will basically upload a file to  
3992.1 -> the bucket so basically we just are testing things  and we haven't done this one here nor the row nor  
4001.94 -> storing to the database and these will come later  so let's open up IntelliJ and within IntelliJ  
4009.68 -> let's open up the main so here open up the main  method and within Main let's basically I'm gonna  
4021.62 -> comment all of this So eventually I'll put this  back or let me just say extract this to a method  
4030.44 -> and here create random and then customer cool so  let me just comment this and within the runner  
4044.06 -> method here itself what we're going to do is  let's basically have the S3 service so s 3  
4054.08 -> and then service just like that and what we're  going to do is we're going to say S3 service  
4062.36 -> Dot and then put object the bucket name has to be  the exact same name of the bucket so if I go back  
4073.22 -> which is FS Amigos code customer test and  then paste that so that's the bucket name  
4080.36 -> and also in here so let me just put this on a new  line also we need to pass the key right so here  
4090.32 -> I'm going to say Foo so that's the key and finally  the byte so what we want to upload so in our case  
4100.76 -> let's just say hello and then world and then store  this as a byte array and literally we can store  
4109.64 -> anything into the bucket cool so basically this  here stores and we should be able to get the item  
4121.28 -> back so here let's basically say S3 service Dot  and then get object the bucket name is the same  
4134.36 -> so the bucket name is the same like that the  key is also Foo the same and this is it right  
4146.24 -> so basically this now is bytes so now if I extract  this to a variable this is the object so I'm going  
4158.24 -> to say object so object like that and what we're  going to do is south and then hooray and then Plus  
4173.18 -> and here I want to say new and then  string and then pass the object inside  
4180.98 -> cool so this is how we turn  a byte array into a string  
4185.72 -> now if we run this we should see that we get back  Foo we should see that we get a low world back  
4194.66 -> let's run it so here right click run Main  give it a second so it's going to start  
4204.44 -> and hooray have a look so we have hello and then  world and this means that we've managed to upload  
4213.68 -> a file into S3 let's check it out so before we  had no objects now if I reload this page in here  
4225.38 -> you can see that in a second why is it slow  my internet is so rubbish seriously cool  
4235.16 -> have a look so this is full and basically we  can download this so click on it and you can  
4244.58 -> download if you want but inside is going to say  hello world which is what you saw in the console  
4252.5 -> and to be honest this is it and also the path  right so basically this is the bucket and this is  
4261.62 -> the key itself now if you want you can store these  you know as a folder structure so you can say  
4269.24 -> forward slash and then images and then full  dot PNG or dot txt whatever right so first I  
4277.82 -> just stored within the root of the bucket itself  now what I want to show you is within dot AWS if  
4287.6 -> I say VI in here and then credentials and  then here if I go to the end of this file  
4296.06 -> and then delete so I'm going to press X so delete  a Escape WQ and if we try to run our code again
4310.64 -> and in here I actually have the AWS plugin  installed which tells me right so this  
4318.62 -> has an invalid database  connection and if I show you the
4325.64 -> plugin so I think plugin and then installed I  think and I think it's this one AWS toolkit so  
4336.38 -> it will basically tell you whether uh there's  something wrong with your configuration or not  
4342.62 -> so go ahead and install it and also you can see  so you can manage buckets and upload and download  
4348.98 -> from packets as well so here I'm just going to say  okay and what I want to show you in fact is if I  
4356.66 -> reload the application this will fail so give  it a second and boom have a look an exception  
4365.66 -> has happened and if we look into the error so  in here scroll up or actually down let's just  
4375.56 -> try and read the error so here have a look right  the request signature we calculated does not match  
4386.06 -> the signature you provided check your key  and signing a method and have a look 403.
4395.3 -> so you can see that how it's important  that you have the credentials configured  
4401.3 -> correctly because otherwise you won't be  able to access the resources within AWS  
4407.12 -> and also our key is admin which means you  can do anything right but if we restrict  
4413.66 -> it and then try to access a resource which  the key is not allowed it will also fail  
4419.9 -> awesome let me hide this and go back  to the terminal and VI credentials  
4426.08 -> so in here so if I go to the end say I so  this was actually t a and then Escape WQ
4438.56 -> and um this is it let's run once more there we  go and you can see that reloaded credentials  
4447.02 -> and in here so the key let's  just say here for example full  
4452.24 -> and then let's just say full forward slash bar  and then forward slash and then Jamila for example  
4461.3 -> right so this right here is the key and if you see  the result of this so let's just run it once more
4472.88 -> there we go so we have Hello World  which was stored if I open up the bucket  
4478.94 -> and here let me just go back now  check this out so full is a folder  
4486.14 -> bar is yet another folder and inside we have  Jamila which is the file that contains hello world  
4495.2 -> this is pretty much it catch me on the next one
4505.4 -> before we move into the controller  and add business logic what I want  
4510.74 -> to do is I want to basically have  this bucket name as configuration  
4515.12 -> so open up application.yaml and in here  you saw that we have AWS and then region  
4524.54 -> let's have S3 in here and then  within S3 we're going to have buckets
4533.9 -> just like that and here we're going to have a  bucket and here called customer and then here  
4544.7 -> and then in here we're going to have the  basically name itself right so the idea is  
4552.02 -> that you can have different profiles and you'll  see this later and you can change the bucket name  
4559.64 -> without having to change code so that is the  benefit of doing this now let's go to Project  
4568.82 -> and in here create a new class under  S3 and we're going to call it S3
4581.54 -> and then buckets press enter here name this as  ADD and then configuration and also add and then  
4591.02 -> configuration properties and this will have  a prefix of AWS dot S3 Dot and then buckets  
4603.38 -> so don't worry about this in here but this right  here AWS dot S3 dot buckets is AWS dot S3 Dot and  
4615.44 -> then buckets and then we can have these as fields  or actually the key as field and then whenever we  
4625.46 -> invoke together we get the bucket itself  so let's go back and here we want to have  
4633.98 -> a field so private don't say final here just say  private string and then customer and customer here  
4644.24 -> is the same as this one here right then let's  basically have the Constructor so add Constructor  
4654.44 -> and oh actually
4658.82 -> I don't even think we need to Constructor  here so there's no need for Constructor so  
4663.02 -> just have the getter and Setter right  so here get it and setter and job done  
4671.78 -> now what we can do is we can  take S3 buckets go to main  
4676.82 -> and instead of saying this we could just inject  basically S3 buckets like that import that and  
4687.74 -> now I can just say so instead of this nonsense I  can just say S3 buckets Dot and then get customer  
4699.02 -> so let's basically try and  reload and see whether this works
4707.6 -> we should get Hello World back and yes we do  cool so you can see that this is a much better  
4713.9 -> approach because later we can have a different  file so application Dash Dev for example with  
4721.82 -> a different bucket name and the same with  the region and basically you can take this  
4728.66 -> and just change it according to your bucket and it  should just work that's another Advantage as well  
4736.34 -> cool this is pretty much it I think  I'm going to let's just take this here  
4744.62 -> and extract to a method and then test bucket  upload and download and we're not going to  
4755.12 -> do this anymore let's just uncomment the create  random user and let's get rid of the service as  
4763.76 -> well as the buckets but be aware that if you want  to use them you just have to import them in here  
4768.74 -> right because this is is expecting them right so  this is pretty much it let me just put this full  
4776.36 -> screen so you see the entire code if you have  any questions and drop me a message otherwise  
4782.66 -> next let's go ahead and create the controller and  then the service and start connecting the dots
4795.14 -> cool so I know that from within IntelliJ we can  run the application and we can store images in  
4801.98 -> here which is nice this bit here this will  be later what I want to focus now is on the  
4808.64 -> controller so we want to expose an API endpoint  to clients and also we want to store the image  
4816.14 -> associated with a customer so let's first  tackle the controller so in here open up  
4823.34 -> project and then open customer controller and  in here we're going to have two methods so one  
4833.36 -> two download and the other one to upload so let's  start with the upload so in here let's say public  
4842.18 -> and we're going to say void upload and  then customer profile and then picture  
4851.54 -> and this in here will have the ADD  and then path and then variable  
4858.98 -> so we need the customer actually in here so path  variable and put this on a new line like so this  
4866.78 -> will be the customer and then ID and you've seen  this which is basically the same thing as this one  
4873.2 -> and let's just take this and in here we're going  to leave this and in here we're going to change  
4881.12 -> this as Post in here so post and then mapping  and this will be forward slash and then profile  
4890.84 -> Dash and then image so let's just say profile  image instead of picture so profile image and  
4900.2 -> this in here will be the ID which is an integer  so integer customer ID and also what we want  
4910.94 -> to receive is so the way that we're going to  receive the file is by receiving the multi-part  
4920.06 -> file and this will come as a request and then  param there we go and this will be called file  
4929.78 -> and this will be a multi-part and then file so  make sure that it's the first one from Spring  
4938.06 -> framework web multipart and here just call it  basically multi-part file or just file if you want  
4947.36 -> add a space in there and this should be it now  because this is a file we have to say that this  
4959.78 -> method in here so this add and then post mapping  and don't worry we're going to add integration  
4966.44 -> tests to make sure that everything works so here  we're going to say consumes so this consumes
4975.44 -> media type Dot and then multi-part  and then form data value  
4986.12 -> cool now at this point in here let's just  invoke customer service Dot and then upload  
4995.66 -> customer and then image we're going to pass the  customer ID as well as the file just like that  
5006.1 -> whoops no like that but like this and we'll create  this in a second so these two methods and we'll  
5016.48 -> create this method in a second so the other method  that we want is let's just duplicate everything  
5023.14 -> and this will be get mapping so get and then  mapping so here we can get rid of this all  
5034.06 -> together and note so in here note the value  okay so here no need for value and the reason  
5043.6 -> why we have value in there is because in here  we have consumes as well so this will be a get  
5050.02 -> basically to get the profile image this will gives  us the byte array just like that I'm going to say  
5060.76 -> get and then customer profile picture no need for  the multi-part in here and let's just say return
5073.24 -> and then customer service Dot and then get
5080.44 -> customer and then profile let's just  say profile get customer profile image
5091.6 -> there we go we pass the customer ID and also  upload customer profile image in there cool so  
5102.16 -> this should be it for these two methods within  our controller next let's tackle the service
5115.9 -> cool in order for us to create these two  methods we did IntelliJ let me just right  
5120.58 -> click show context action create method and it  takes me straight into the method in here on the  
5128.98 -> service class let me go back and do the same for  get customer profile image and there we go cool  
5137.68 -> so in here this is going to be straightforward  because we already have the service that allows  
5143.86 -> us to upload and download so scroll to the  top in here and what we need is to have the  
5154.06 -> private final and then S3 and then service so  the one that we just use within the main class  
5161.44 -> add this to Constructor here just say  refractor will go into the test in a second  
5167.56 -> and this is it if I scroll down so what we  need to do in here is before we upload we  
5178.78 -> want to get the customer or in fact check  whether the customer exists so let's just  
5184.9 -> copy some code and we could basically  extract this to a variable and basically say
5196 -> check if customer exists cool now we can reuse  this so here I could say check if customer exists  
5210.34 -> or let's just rename this to or so refactor rename
5216.4 -> or and then throw there we go so here pass the  customer ID and if this is the case it's just  
5227.26 -> gonna throw and execute the remaining lines now in  here what I want to do is I want to say S3 service  
5236.74 -> Dot and then I want to put so this allows us to  upload the bucket so the bucket will come from  
5246.52 -> let's scroll up in here and private final  and then this will be S3 and then buckets  
5259 -> or we could just call it buckets to be honest  so that we're not tied to S3 but that's fine  
5268.3 -> so here scroll down and where is it so it's not  even the lead customer it's this method right  
5281.68 -> here right so here we want to get the bucket  so I'm going to say S3 buckets dot get customer  
5291.22 -> and the key will be under a folder called profile  and then images forward slash and then percent s  
5305.2 -> forward slash percent and then s dot and then  formatted and we need to pass the customer ID  
5315.52 -> but also right so this will be customer ID so that  we organize things by customer and then here the  
5325.06 -> ID for the picture so the ID for the picture so  this will be you with Dot and then random uid  
5334.18 -> Dot tostring and finally so comma so literally  after this so basically this close in parenthesis  
5345.4 -> so comma there and the actual file so  basically say file Dot and then get bytes  
5354.94 -> now this here this is a checked exception  so let's just surround we try and catch  
5361.06 -> so surround we try and catch and I think  this is pretty much it right so also let's  
5370.96 -> extract this ID here so we're going to  extract this so I'm going to say profile
5379.9 -> and then image and then ID and let's put this out
5391 -> and let's take this and put it outside like so  cool so if it fails then we want to throw so throw  
5404.32 -> new and then let's just say run time exception  so at this point I'm not worried too much about  
5411.58 -> exceptions but if you want to organize these  exceptions and have better messages you know  
5419.02 -> that within so if I show you so exception  we have the where is it default exception  
5428.38 -> Handler and in here you can basically handle  all of the exceptions and have proper error  
5434.98 -> codes but for now let's just get the meat of S3  and file uploads and downloads up and running  
5443.14 -> cool so let's go back to customer service and  this is it now one thing that we have to do is  
5451.72 -> so upon completing this so here let's just have  it to do so to do and then store and then image  
5464.02 -> yeah so we'll do this in a second cool next let's  go ahead and Implement get customer profile image
5478.54 -> cool now let's Implement get customer profile  image and I've just basically need to make sure  
5485.38 -> that this store image so this to do here is to  postgres so post address and basically store  
5495.64 -> profile and basically store profile image ID so  basically profile image ID to postgres or 2db  
5506.68 -> cool so now get customer in here so what we want  to do first is get the customer so if I scroll up  
5515.74 -> you can see that this is how we get the customer  so here we just copying code I left copying  
5524.02 -> code so here we're going to paste that we're  going to get the customer and that's it now  
5533.2 -> we need to do few things so one is so here I  want to say to do and we'll do this in a second  
5540.88 -> check if profile image ID is empty or no  
5554.62 -> right so if so then we say that the customer  doesn't have a picture associated with and  
5561.4 -> then what we do is we get the we get the  profile image ID so here let's just say string  
5570.7 -> and by the way you are free to use VAR for example  okay so let's just use VAR here so VAR and then  
5578.56 -> I'm gonna basically say profile image ID for now  so this will be to do as well in a second so to do  
5587.98 -> and we can say return so in here return and then  S3 service Dot and then get object so D bucket is  
5603.28 -> S3 buckets Dot get customer and then  the key so the key is the same one  
5613.24 -> that we stored so where we put the object  itself so let's just paste that in here  
5623.32 -> and this is pretty much it and then basically end  this with semicolon and basically this right here  
5631.78 -> so if I extract this to a variable so you see  so this is the picture itself so pick sure right  
5640.66 -> or image or profile image profile image and then  profile image so it's easy for you to see this way  
5652.6 -> and yeah so this is pretty much it obviously  here we're not doing anything with customer  
5658.54 -> and that's because we are going to in  a second right so this customer will  
5664.12 -> contain so I think is it this customer so  select by D where do we perform the mapper  
5675.34 -> so let's have a look yes I think we  need to even map this customer in here  
5682.12 -> so yes absolutely right so here let's just say  dot and then map and then I think it's close and  
5691 -> then I think it's customer roadmaper cool so  then this will basically gives us a bunch of  
5697.36 -> fields excluding the password and stuff that  the client doesn't really need to know right  
5704.62 -> so we'll touch on this next but basically  this is the implementation next before we add  
5713.32 -> the profile image to the database let's quickly  open up the test class so customer service test  
5720.64 -> and you can see that this basically it's  complaining now so let's just take this  
5727.78 -> and basically put it on a new line like this and  what we need to do really so quickly is have a  
5737.86 -> mark so I'm going to say at and then mock for  the S3 service so S3 service and also a mock for  
5749.8 -> the so private and then S3 and then buckets cool  so we're not even writing tests at this point  
5760.3 -> because we're not done but I just want to make  sure that we fix the compilation error cool so  
5766.9 -> now that we have everything ready next let's worry  about storing the profile image ID to the database
5781.54 -> cool let's go ahead and shift our attention in  terms of storing the profile image ID to the  
5789.58 -> database so we want to take basically this value  in here and then store it against the customer  
5799.54 -> that we upload so that when we perform the get  in here we know exactly the key that needs to be  
5810.04 -> assembled in order to download the latest profile  image so the first thing that we're going to do  
5817.24 -> is open a project and open DB migration and  inside we're going to have a second migration  
5827.26 -> so I've just copied or in fact let's just  right click new and then do we have SQL in here  
5837.1 -> so SQL no I don't think I can search but basically  let's just say V and then 2 underscore underscore  
5848.44 -> add underscore customer Pro  file and this score image
5861.4 -> and then dot SQL cool so this is the SQL in here  and what we want to do in here is simple so alter  
5873.88 -> table customer so this is the name of our table  and then we're going to say add and then column  
5882.88 -> and the column in here will be profile  and the score image and the score ID
5895.84 -> and in here let's just say VAR char and  then 36. so I think that's the value or  
5903.28 -> the length of uits so here don't even  say not no because that's not the case  
5909.58 -> right and also this will actually fail because  we have customers with empty profile pictures  
5917.62 -> right so this should be something optional  and also I don't want the profile image ID  
5922.84 -> to have duplicates so to mitigate against that we  just say alter and then table and then customer
5934.18 -> and here we're going to  say add and then constraint
5942.16 -> and here we need to basically  give a name so this will be  
5946.66 -> unique underscore and then profile image ID  and then just say unique and then here so let's  
5958 -> basically put it on a new line I think just like  that and basically we have parenthesis and where  
5966.4 -> this is unique is on the profile ID just like that  cool and this with semicolon and we are good to go  
5977.92 -> cool now let's open up the customer class so  here customer and then class so basically this  
5988.18 -> class or this entity and if I put this full screen  so in here what we want to do is so let's start  
5995.32 -> with the column so here scroll down and after the  password just say private and then string profile
6008.7 -> and then image and an ID this will be a column
6015.42 -> just like that and here this  will be unique equals to true  
6022.38 -> and also we want to do the exact same thing as  we've done with email so here let's just take this  
6029.52 -> comma paste that and then this will be the  column that we've just created which is this one  
6038.16 -> so where is it this guy here so the  column and what do you call it so we said  
6047.7 -> let's just switch this around so profile  image ID and the score and then unique  
6056.76 -> so let's take this go back and paste it  here and now we can basically match the  
6067.2 -> schema with our entity which is really nice  also so the column actually is this so that's  
6074.94 -> the column in here so the same way that we've  done with email nice now let's basically remove  
6084.6 -> so we're going to remove the two string in  here we're going to generate this once more  
6091.56 -> there we go and also the equals and hash  code let's just get rid of all of this  
6100.14 -> and before we create that actually let's just say  get the image profile and also set the profile  
6113.4 -> right and now at the bottom let's just create the  equals a nice code so next next next and then next  
6124.26 -> and also two strings so two and  then string select all of those  
6130.92 -> and possibly we don't need the password in here  but I'll just leave it and this should be it  
6140.94 -> and also I want another Constructor with basically  all these so name oh actually sorry this one here  
6152.58 -> so ID name email all the way to  gender so let's just take all of that  
6158.46 -> so we're going to have another Constructor  that basically takes the string and then  
6166.86 -> profile image ID and what we're going to do  is instead of setting these manually we could  
6173.94 -> just say this and then pass basically there's no  Auto completion ID name email and then password  
6185.22 -> age gender and finally we say this dot  profile image ID equals to profile image ID  
6198 -> awesome this is pretty much it now let's  try and start the application so run Main  
6206.94 -> let's just run this and hopefully everything  should just work and it failed so let's have  
6214.02 -> a look why enable to create constraint on  so it says that the column profile image ID  
6224.22 -> not found oh yes so it's not found because so  basically this is the name so profile image ID  
6234.54 -> in here so instead of actually not here  but here so I thought it was the SQL  
6242.88 -> column in here but now it's the  entity so paste that and then run it  
6251.46 -> fingers crossed should just work and hooray  you see that it works and we have an insert  
6261 -> which comes from the main class awesome this  is pretty much it catch me on the next one
6272.7 -> cool if I open a project and  remember we have the customer  
6277.8 -> not customer dto but customer Dao and in  here so in here we have select all customers  
6287.7 -> and basically when we select customers we're  gonna have to select the profile image ID as well  
6298.32 -> and also if I open up where is customer service  so customer service in here so we need the ability  
6310.14 -> when we upload we want to update the customer  profile image ID with this new one which is  
6319.56 -> basically here right so let's start there and then  fix the select So within customer Dao we're going  
6328.26 -> to have a new method in here and the reason why  we have this interface is because we are using  
6335.04 -> both jpa and jdbc so here let's together  say void and then update customer profile  
6348.36 -> image ID in here we're going to take  the ID right so image profile or profile
6359.82 -> and then image and then ID and then integer  
6365.28 -> and this is the customer ID  so customer ID just like that
6372.72 -> and let's fix in here so customer  ID so that we are consistent  
6379.62 -> and now we need to Implement basically  customer jdbc data access service  
6386.64 -> we need to implement methods update so this one is  straightforward and is a symbol AS saying VAR SQL  
6397.56 -> and the SQL within it is going to be update and  then customer and then here set and then profile
6413.88 -> and then image and Discord ID equals to and then  a value basically cool so we have basically the  
6425.46 -> SQL statement in here and all we have to do is  just say return or not even return because this  
6431.64 -> is void so we just have to say jdbc template Dot  and then update SQL and here we have to pass the  
6441.42 -> arguments so profile image ID and customer ID  and there we go you can see that this actually  
6450.3 -> now is highlighted for whatever reason which  I'm not entirely sure so let's just indent this  
6457.86 -> and hold on so I think what I want is it that  it's weird it's at the same level as this one  
6467.58 -> no so why why are you playing up IntelliJ so this  is pretty much it now for the other implementation  
6477.78 -> so customer dial then we have the jpa so this  is quite easy so let's just Implement methods  
6486.9 -> and in here what we are going to do so let me  just expand all so what we're going to do is  
6495.6 -> within the repository so customer repository  we're going to have one method in here so  
6501.9 -> this will be at and then modifying and at  and then query so we want to have a query  
6510.54 -> and the query for this will be so I think this  returns an integer whether it worked or not or  
6518.04 -> the number of rows affected actually so here we're  going to let's just say first set and then profile  
6528.84 -> and then image ID so we need to receive the  string profile image and then ID and then  
6539.76 -> the customer or actually integer customer ID and  within the query itself so this is where we have  
6549.78 -> basically jpql so update and I think we can do it  uppercase so update and then customer and then C  
6561.48 -> set and then C so the customer dot profile  image ID equals to question mark and then one  
6572.94 -> where C dot ID equals to question mark and  then two so this C right here is this one so  
6585.06 -> this is how it works and then from here we can  basically access the attributes to perform our  
6591.06 -> query cool so now we have this query right here  so set or we can even say update let's just say  
6599.58 -> update profile image ID and let's go back to the  data access service scroll down and in here we're  
6611.28 -> going to say repository so customer repository  Dot update profile image ID pass in D image ID  
6621.72 -> and the customer ID and this is it we also need  so we have a third implementation customer list  
6632.4 -> which at this point I think we might just delete  it all together because we're not using this right  
6638.82 -> so this is just a static list in here so I'm going  to leave it here just in case you want to play  
6645.84 -> around but in here I'm gonna say to do implement  this cool and let me just add an emoji here  
6660.12 -> and then this all right cool so this is pretty  much it one last thing that we have to do  
6672 -> is within the customer jdbc data so this  guy here within this selects we have to  
6681.18 -> select basically the new column that we just  added and that's what we're going to do next
6692.88 -> now let's go ahead and open the customer jdbc data  access service which basically uses jdbc and in  
6701.94 -> here when we select all customers let's include  our brand new column called so if I show you the  
6710.04 -> migration so this is a new column so let's just  take this command C go back and then paste that  
6718.38 -> cool now I think we also need to select it here  comma and then there and so when we insert we  
6728.04 -> don't have to insert the new column so also we can  get rid of this right here so we no longer need  
6736.56 -> that or in fact it's just because of this right so  we can get rid of all of that so we don't use that  
6743.64 -> cool so let me just scroll down so exists we don't  need delete also so at this point I'm going to or  
6753.3 -> you know what let me just leave the results there  cool so maybe for debugging purposes but usually  
6759.18 -> you wouldn't have these print line statements  so let's scroll down update customer all good  
6767.94 -> So In Here Also select user buy and then email  we want to select the new column just like that  
6778.02 -> and we have this brand new method that we  just added update customer profile image ID  
6785.82 -> now what we want to do is  the following so we want to  
6794.34 -> change so if I show you where is it so we have  the customer row mapper So within customer  
6801.6 -> real mapper we have to change it slightly so  now here we need to include the new column  
6809.82 -> so here say comma and we're going to say RS Dot  and then gay string and then paste the new column  
6820.86 -> now remember we have this new Constructor so this  one here that we added so that's the reason why  
6827.22 -> we did this so that we can also provide the  profile image ID cool and I think this should  
6836.52 -> be it we'll run the tests and if there's any  failures we'll fix them in a second but I think  
6843.78 -> this should be it if you have any questions drop  me a message otherwise catch me on the next one
6854.64 -> all right so let's go back to our to-do's in here  so within upload customer profile image and their  
6862.38 -> customerservice.java and let's fill in the gaps  but as I said we'll focus on testing and make  
6868.86 -> sure that basically everything is working so in  here what we have to do is we have to basically  
6875.1 -> store the profile image now the way we're going to  do this is by invoking the Dao so customer Dao Dot  
6886.62 -> and then update and then customer profile image  ID so you see how this is coming together so here  
6895.56 -> the profile image ID is the profile so profile  image ID just like that comma and then customer ID  
6907.08 -> cool so basically what we do is  we check if the customer exists  
6913.08 -> then we generate the profile image ID we store  that within AWS if this fails then we don't update  
6921.72 -> if this exceeds we basically reflect that in the  database and when we get the profile image in here  
6932.4 -> we have the customer we perform a select customer  by ID we have the customer row mapper so customer  
6942.54 -> dto row mapper if you look into this guy here  this needs the ID so let's just here say comma  
6952.68 -> and then customer Dot and we have the profile this  guy here now obviously the dto itself right so the  
6965.04 -> dto itself doesn't have the ID so let's go into it  in here and we can refactor let's just refract it  
6975.9 -> like so so right click and then refactor change  signature in here I'm going to add so add so  
6985.56 -> click on the plus sign so this will be string and  the name is customer profile [Music] or profile
6999.36 -> image ID and for now let's just refactor  this cool so basically indent things  
7008.96 -> and now so wherever we use the dto and you can  see that there's a bunch of tests in here that  
7015.92 -> we might have to go into and change this around  but if I go back to customer detail mapper now  
7023.12 -> you can see that this error went away now let's  go to customer service and within customer service  
7031.04 -> in our beautiful method in here so we get the um  customer here so at this point we map the customer  
7041.42 -> to the D dto and now here we have the profile  image ID so what we can do is so in here let's  
7053.36 -> just get rid of this all together and then put  it here so customer Dot and then profile image ID  
7063.26 -> and also we want to check right so if  so if for whatever reason the customer  
7073.1 -> and then Z profile image ID so  here I think we can say is and then
7084.26 -> blank in here so if it's blank right we  basically throw so we're going to throw  
7092.72 -> new resource not found exception and then let's  just take this put it here on the new line  
7104.54 -> and I want to say customer so customer  with ID and then blah and then profile
7116.72 -> image not found instead cool and this is pretty  much it so obviously here if you want I think we  
7126.44 -> can change this to a VAR so I wanted to use vars  throughout this so yes we can and also if you want  
7134.36 -> you can just return but let me just keep this as a  byte array so that you know the data type for this  
7141.86 -> cool as I said if you want you can inline this if  you prefer just like that I think it's better but  
7147.26 -> for readability I'm going to leave it as so and  this is pretty much it catch me on the next one
7160.58 -> cool before we move any further let's just  try and run all tests in here so let's open  
7168.8 -> up tests and not the integration tests for now  let's just run all the tests and the customer  
7176.6 -> so I want to make sure that everything works  and yes so we have a compilation error which  
7182.54 -> we have to fix and that's expected because  of the dto so in here remember so I said that  
7190.82 -> so have a look so we have the customer dto  so this guy in here I think is going to be no  
7198.44 -> so there's no profile image there if I press  f2 this takes me to the next error so have a  
7206 -> look F2 next highlighted error and this  also is the dto so I'm going to say no  
7214.52 -> just like that and let's  try and run the tests again
7222.44 -> cool so I think that was it  now it's running all tests  
7229.16 -> and everything passed apart from the row mapper  now this roadmaper let's have a look why it's  
7236.6 -> failing so click on difference and it looks  like the password is null and the profile  
7250.64 -> so okay so this is no so why is it a password no  so I thought that we had this fixed but maybe not  
7261.5 -> so let's just in here let's go to the customer  row mapper so command e customer row mapper  
7273.02 -> and in here so we made a change to include the  profile image ID that's fine if I open up the  
7281.48 -> test class for this so we didn't change the  test class so here we don't have the password  
7291.62 -> right so I think that we forgot to add the  password before and if we look into the customer  
7302.48 -> so probably it's because  now the two string contains  
7308.3 -> basically everything right so what we are going  to do now actually so let's just basically say oh  
7317.9 -> in fact we should have actually so if you look  into customer row mapper RS dot string right  
7323.66 -> so this is actually returning no okay so that's  why it's now so let's fix this so let's here say  
7331.7 -> basically duplicate this and  then when and then password
7338.36 -> so we want to return password just like that  and also so yes so also we're not even comparing  
7352.04 -> the new column right so if you want you can  basically add it as well so this was customer  
7361.52 -> or actually it was a customer so what was it  so here profile image ID so profile image ID  
7371.42 -> and then here I'm going to say basically I'm going  to say profile image ID or actually let's say one  
7378.86 -> two or two two two five twos cool so this now so  we can change this to B five twos and let me just  
7390.08 -> put this all in a new line just like that so this  is much better oops like this like this and let's  
7402.86 -> now try and run tests so in here click on run  and I want to run only the failed tests for now  
7415.1 -> and yes so this works cool so let's  run all tests once more so in here  
7424.1 -> I think yeah so if I close  that let's run all tests  
7429.62 -> just to make sure not that but all tests so  open project and then this will be customer
7440.48 -> there you go I think yeah so 38 tests should  pass Bingo and now let's basically run everything  
7451.28 -> including integration tests so at this point  make sure that your database is up and running  
7459.02 -> with docker so the integration tests I think  they they run already yes one of them did and the  
7468.08 -> authentication ID or the authentication ID also  run and you can see that we do have every existing  
7476.66 -> Test passing cool so one thing here so customer  service so this guy in here so customer service  
7486.86 -> so not the test but the actual class so we have  get customer profile and also upload customer  
7495.86 -> profile in here and within S3 so S3 where's  S3 so Java not on the test so in here so S3  
7509.12 -> buckets so this doesn't need any tests S3  config probably this doesn't need any tests  
7517.58 -> and S3 service so this we can test this  here as well right so next let's go ahead  
7525.8 -> and focus on testing so we're going  to write unit as well as integration  
7532.28 -> tests if you have any questions drop me a  message otherwise catch me on the next one
7542.06 -> testing is something which is kind of out of  the scope of this crash course but yet very  
7548.96 -> important so you saw that we wrote lots of  code but how do we guarantee that the code  
7554.36 -> that we wrote does work well we have to write  tests okay now I always ask this question would  
7561.38 -> you ever board on a plane that hasn't been tested  and the answer is absolutely no right so there's  
7568.22 -> no chance that you'd risk your life so it's  the same thing with software so in this crash  
7572.72 -> course I'm going to skip testing all together  um the actual videos but I'll show you that I  
7579.74 -> actually you know tested the entire thing  including unit testing mocking as well as  
7584.78 -> integration tests right so this is the beauty so  once you test everything then you have you know  
7591.56 -> um you know you're a bit confident um in the  sense that you know that your code will work  
7597.98 -> if you deploy to an environment such as  development or testing or production so  
7604.82 -> make sure to test your code and as part of the  full start course I covered testing from the  
7613.04 -> ground up and basically everything you need  to know about testing but testing is out of  
7618.62 -> the scope of this crash course so um yeah this  is pretty much it and catch you in the next one
7630.38 -> if you've managed to get this far in here what I'm  going to do is the following so let's look at the  
7636.68 -> stop this and open up the terminal and in here  what we're going to do is we're going to say git  
7645.26 -> checkout and then Main so basically this now will  contain all the tests so I'm not showing you how  
7653.78 -> to write all the unit tests as well as integration  tests but I just want to show you that we do have  
7660.14 -> a bunch of tests in here so I'm gonna leave things  as this in here and so the changes that I've made  
7668.78 -> so if I open up the test folder and then S3 you  can see that we have a bunch of tests in here  
7676.52 -> and also for customer we change things and we  tested everything fully as well as an integration  
7683.36 -> test under so under Journey and then customer ID  and if I scroll down in here you should see that  
7691.46 -> we have so if I scroll down in here so can upload  and download profile pictures and basically we  
7701.24 -> test all of this now I would say from this point  onwards right so everything should just work the  
7707.6 -> same so when we deploy things but if you want to  see how I wrote the tests and whatnot just check  
7714.62 -> out domain and then Carry On from there okay so  in here so let me just basically run all tests  
7722.6 -> and you'll see that whoops so in here  why isn't this working right okay cool  
7730.46 -> so let's together click on file and then  invalidate caches and invalidate and restart  
7740.66 -> there we go and hopefully this should  fix itself just give it some time now  
7745.82 -> cool still that didn't fix so let's  try to in here reload the project
7755.72 -> and there we go cool so that fixed the problem  so this sometimes you'll encounter these issues  
7763.46 -> so here we've just fixed during the course which  is awesome and cool so let this finish and now  
7772.46 -> we are able to run the tests so let's just run all  tests and tests it's vital in any application okay  
7782 -> so if you don't know testing so I'll urge you  to learn about testing so you can see 56 tests  
7789.92 -> and everything just ensures that we have the  correct implementation awesome so this is pretty  
7798.98 -> much it if you have any questions on testing  as always you can ask and I'll try my best to  
7804.98 -> advise you otherwise you can check the courses  that we have on testing and as part of the full  
7811.52 -> stack where we learn where you learn all of this  I'll show you how to basically test so in S3 what  
7819.92 -> we've done is we created a fake implementation  which is used for unit testing purposes so this  
7827.12 -> actually stores images in our local file system in  here you can see that this is the implementation  
7833.48 -> for basically running the application locally  without us having to connect to AWS directly  
7840.2 -> cool I'm going to leave it here let me just close  this and this as well and this is pretty much it
7851.78 -> what I want to quickly mention is if you  want to upload larger files you need to  
7857.9 -> configure the application.yam also and the spring  
7862.46 -> and then have the servlet and then here include  multi-part Max file size Max request size and  
7871.28 -> also Max in memory size so with all of this  you will be able to work with larger files  
7878.06 -> so in my case 10 MB is absolutely fine but if  you are uploading videos and other files then  
7886.58 -> you might to increase these numbers so go ahead  and add these so that you can work with larger  
7892.28 -> files and actually before I go let me just show  you that the default so max file request size  
7898.52 -> so the default is 1 MB in here the same for  this one oh this one is actually 10 MB and  
7907.4 -> then the max in memory is 256 kilobytes awesome  this is pretty much it catch me on the next one
7923 -> for this section what I want to implement is the  ability for us to update the profile in here so  
7930.86 -> if I click on update and what we want to have is  the ability of dragging and dropping any picture  
7937.88 -> in here so if I basically get these pictures  that I have in here and this is Maisha and it's  
7945.74 -> a male and let's say that here I want to take  this picture and then upload just like that so  
7950.96 -> I can drag it actually in here or I can click  in there but eventually this should upload so  
7958.52 -> I think it was my issue so let me just search for  Maisha there we go and you can see the animation  
7964.1 -> now in here has the picture updated so again if I  click on update you can see that the picture now  
7972.02 -> it's present in here and I can basically click  in here and this will bring the pop-up where  
7978.68 -> I can where I can select pictures if I cancel  and basically this is what we want to achieve
7989.84 -> in order for us to upload files or in  our case a profile image from our react  
7996.5 -> application to our backend we're going to  use this Library called react Drop Zone  
8002.98 -> so this is a library that basically makes it  super easy to create drag and drop zone for files  
8010.72 -> and in here you can see the usage and you can  find the link in the description of this video  
8015.04 -> but basically it's very simple and you  could just use the hook in here or the  
8020.68 -> component and then you have the ability  of uploading files to any destination  
8028 -> so let's go ahead together and install the react  drop zone so let me just take this command in here  
8036.7 -> go back to IntelliJ and within IntelliJ if I  open up the terminal and in here we can open  
8042.94 -> a new session and let me CD into front end and  then angular and then react and inside let me  
8053.5 -> just paste the command so npm install and then  dash dash save react and then drop zone press  
8060.1 -> enter and to be honest this is pretty much it next  let's go ahead and learn how to use this Library
8074.92 -> cool you saw when we run the back end we  basically get a customer which is added  
8080.98 -> to our database so in here let me just take  this customer and this is from the logs from  
8085.84 -> our spring blue application and let me first  log in so here localhost and then colon 5173
8098.8 -> and I want to add the email that I've just  copied and the password is just password
8105.1 -> and then login and here if I go to customers you  can see that we have Christopher and basically  
8111.76 -> this is what we want to implement right so  Christopher um basically this is a random name  
8118.24 -> which is generated but basically this picture  right here is randomly generated and we want to  
8124.78 -> have the ability of when we click update and here  we want to have the Drop Zone component in here  
8132.16 -> so that we can upload a picture to our backend so  let's open up this component in here and add Drop  
8141.34 -> Zone and in here if I Collapse this and then open  up the front-end folder we have react and within  
8150.76 -> react we have SRC components and then customer  and in here we have the update customer drawer  
8158.98 -> as well as the form so what I'm interested is the  form itself so here let me just collapse this and  
8166.36 -> if I scroll down you should see that we have the  form itself in here update customer form now here  
8173.56 -> at this point is where we want to add the Drop  Zone component so actually just before here so  
8181.36 -> basically if I say H1 for example in here and then  say hello go back you can see that we have hello  
8190 -> in here right so hello but we want this to be the  Drop Zone where we basically can upload a picture  
8197.979 -> So within the documentation for Drop Zone you can  see that the usage is quite straightforward so  
8203.8 -> they basically give you the option of using the  hook or the wrapper like so so what we're going  
8211.84 -> to do is let's it doesn't really matter which  one you use but let's use the hook in here so  
8218.14 -> just take this in here so take this command C and  you can find this in the description of this video  
8226.24 -> and then go back and just before this form let's  have the drop zone and by the way so this right  
8235.479 -> here I'm not going to have it as a component so  that you can reuse it I'll leave that up to you  
8241.18 -> so I'm just going to leave it in this file for  now so this is where we need it so I'm just going  
8245.8 -> to leave it here so here I'm going to leave the  name as my drop zone you can rename this if you  
8250.84 -> want then we have to import the use callback so  let's just import that and use drop zone as well  
8260.08 -> so let's just import that from react Drop Zone  just like that and this is pretty much it so now  
8268.479 -> at this point let's also so rename this so drop  the and then picture here and then drag and drop  
8279.16 -> and then picture here or click to  select picture select and then picture  
8287.38 -> there we go so this is much better  and what we're going to do for now is  
8293.62 -> take this so actually let's just change this  from const and then my drop zone equals to
8303.64 -> so basically equals to a function this is an arrow  function actually and this is much better cool so  
8311.439 -> now let's basically in here instead of hello  we're going to say my drop zone just like that  
8318.22 -> and this can be a self-closing tag so let me just  remove all of that there we go and if I open up  
8326.26 -> my web browser now you can see that it says drag  and drop picture here or click to select picture  
8333.46 -> so basically I can drag a picture or I can click  to select so here if I select or click my bad you  
8342.64 -> can see that it opens the window Explorer where  I'm able to pretty much just select any picture  
8350.02 -> cool let me cancel out of this next  let's style this component in here
8361.359 -> all right let's change this component so it looks  a little bit more appealing so let's open up  
8366.82 -> IntelliJ and within IntelliJ if I open up my drop  zone in here and what I want to do is you see here  
8375.28 -> we have this div in here so I'm going to change  this from a div into a box in here so just say box  
8385.54 -> and this comes from Chakra UI and at this point I  can basically customize it so here so here within  
8397.359 -> here basically within the Box itself right so I  want to add the width so w and this will be equal  
8408.1 -> to 100 and then percent I also want to align  so text and then align and this will be Center  
8418.06 -> and let me just format things and also let's add a  border oops Border in here and the Border will be  
8428.08 -> dashed let's also Define the border and then color  so border and then color and this will be Gray  
8439.359 -> and then let's say great.200 let's also add  some padding and here I'm just going to say six  
8446.859 -> and you can basically fine tune these numbers  according to your liking let me also say that this  
8452.26 -> box will be rounded so rounded and here I'm going  to say let's just say MD for medium So within  
8462.1 -> quotes just like this and also the Border radius  so border and then radius so this should be in  
8475.479 -> here so color and then the radius so this should  be something like three Excel so three Excel  
8485.62 -> all right so let me just put that in there  like so now scroll down where we actually  
8492.04 -> use the Drop Zone let's cut this and I'm going  to encapsulate this within a V and then stack  
8500.859 -> just like that and within this v-stack let's  add some spacing so you can say spacing  
8508.12 -> and here I'm going to say five let's also  add margin and then bottom so MB and this  
8516.64 -> will also be five now if I paste the Drop  Zone like so and let's basically save this  
8526.78 -> go back and you can see how this is  looking so it's looking really beautiful  
8532.24 -> so let's also add an image in here in case there  is one so let's go back and in here I'm going to  
8541.18 -> say image so make sure this comes from Chakra as  well and in here we can basically pass few things  
8549.399 -> so one is the Border and then radius so this will  actually be full so I want this to be completely  
8557.979 -> a circle and then box and then size let's say 150  pixels so 150 pixels like so and object fit so if  
8571.84 -> the image is too big I want it to fit basically  so I'm just going to say cover so cover and we  
8580.72 -> also need the SRC which we'll add in a second but  this is pretty much it so I think for SRC we need  
8590.26 -> to add an empty string in here cool if I go back  to Chrome you can see that basically we have this  
8597.58 -> circle in here which is an empty image and when we  drag and drop the picture this right here should  
8605.14 -> be reflected next let's take the picture that  we upload in here and save it to our backend
8617.38 -> cool The Next Step that we need is when we drag  the picture in here or when we select the picture  
8623.74 -> to upload it to our backend and then from our  backend it goes to S3 or to our local file  
8631.06 -> system depending on the implementation so let's  open up IntelliJ and within IntelliJ let's open a  
8639.28 -> project and within project open services and here  client and in here we're going to have two methods  
8648.939 -> so let's basically say export and then  const upload and then customer profile
8660.7 -> and then picture and equals to A sync and in  here we need to take the ID and then the form  
8669.819 -> and then data so basically I'll show you this  in a second so when we pass the information but  
8679.54 -> now let's say try and within this try and catch  block we're going to return the acios so acios  
8688.84 -> Dot and then this will be a post and let's  take this right here so this will be the same  
8697 -> across basically everything say back ticks  and within backticks have the dollar sign  
8704.979 -> and then curly bracket and then paste oh  actually I just had it there just like this and  
8711.1 -> then say forward slash API forward slash and then  customers forward slash V1 forward slash customers
8723.1 -> and then dollar sign oh actually  forward slash and then dollar sign ID  
8729.7 -> and what we need so let me just  put this on a new line like this
8737.56 -> there we go so then we say forward slash and then  the end point which is profile Dash and then image  
8746.979 -> so this right here is the  controller so here remember  
8754.3 -> the customer controller in here  customer ID profile image let's go back  
8761.92 -> and in here so let's just say comma and we  need to pass the form data as the payload and  
8770.92 -> also the headers so here this will be an object or  actually the config which is going to be an object  
8778.66 -> and basically I want to get the token  so say dot dot and then get auth config  
8787.06 -> but also what I want to add is so here I want to  add content and then type so content Dash type  
8799.96 -> and this will be multi-part  forward slash form and then data  
8809.5 -> so have a look so if I open up customer  controller this is exactly what we've  
8814.72 -> done before multi-part form data so here  I'm just specifying on the client as well  
8821.979 -> and this should be it now let's basically end this  with semicolon and we're going to basically catch  
8831.16 -> e and at this point I'm going  to throw oops not tribe throw
8839.5 -> and then e and it's as simple as this  
8844.3 -> cool next let's use this method  within our Drop Zone component
8855.939 -> okie dokie so let's open up the update  customer form and inside of our Drop  
8863.08 -> Zone in here so instead of the job Zone  you can see that there's a method on drop  
8870.46 -> so on drop has the accepted files and what  we are interested is in just one file right  
8878.08 -> so basically we just upload one file and process  that so what we're going to do is we're going to  
8884.02 -> use our method called upload and then the profile  picture in here and we need to pass the ID so  
8894.46 -> let's just say ID which we don't have and I'll  show you in a second how we're going to pass that  
8899.319 -> and then the form so form and then data which  we also don't have and I'll show you in a second  
8908.74 -> all right so what we're going to do is the  following so in here we need to create first  
8914.92 -> the form data object so const and then  form data equals to new and then form  
8924.16 -> and then data like so and within form data  so I'm going to say form data dot append  
8932.08 -> the file so file and then comma and then accepted  files and I want to grab the very first file  
8941.439 -> just like that and this is basically the  form data now this name in here so name  
8950.26 -> file is basically what we accept in here  multi-part file the request param which is  
8958.42 -> file so it has to match with a client sense  so if I go back in here and now we need to  
8968.2 -> pass the ID now the ID will be passed as a prop  so basically have curly brackets and then say ID  
8977.2 -> and the way we get the ID now is so in here  where we use the drop zone so in here have a look  
8986.08 -> update customer form fetch customer initial  values customer ID so here let's just say customer  
8995.74 -> or actually ID and this is customer ID  and in fact let's just call it customer ID
9006.06 -> so where is it so customer ID so now you can see  that this Drop Zone actually is mainly focused  
9014.939 -> on customers right so I'm not refactoring to be  generic because I don't have to at this point  
9021.84 -> I just needed to upload profile pictures but  if you want to refactor go for it so here we  
9028.5 -> need to also pass the customer ID instead  of ID and job then now this is complaining  
9036 -> because we need to say dot and then then so if  basically we have the response so R in here or  
9044.22 -> res which I'm not going to do anything with it  so I'm just going to say success notification  
9052.5 -> and then I want to say success and  let's just put this on a new line
9059.7 -> just like this success notification that's  the title and then I'm going to say profile
9070.979 -> and then picture uploaded so if this fails  so then and then here I'm going to say dot  
9082.14 -> and then catch and here basically the error and  if there's something wrong with it this actually  
9091.979 -> has to be like this so air and if there's  something wrong with it I'm just going to say  
9099.899 -> I think it's Error notification yes air  notification and here I'm just going to say failed  
9107.399 -> or error it doesn't really matter you can  choose whatever message you want for the title  
9112.56 -> and description so profile picture upload  and then oh actually let's just say failed  
9118.8 -> failed upload and it's basically like this  right and also if you want you can say log  
9126.54 -> and you can log the error to have more  visibility but for us I'm going to remove  
9133.319 -> all of this in fact and also the response so  we're not doing anything with it so we just  
9139.68 -> leave it as is and to be honest I think this is  pretty much it next let's go ahead and test it
9152.819 -> and see whether we have uploaded a  picture for this customer in here  
9159.3 -> So currently it's not storing to S3 because the  implementation is to store in my local machine so  
9166.56 -> in here I'm within the database and if I say  select and then start from and then customer  
9175.8 -> and let me just say backslash X and then run the  exact same command and you can see that we have  
9183.78 -> the profile image ID in here and the customer ID  is 43. so let me just open a new shell like so  
9193.62 -> and I'm going to CD into so basically dot Amigos  code and then S3 and inside we have the folder  
9206.58 -> or basically this is the bucket name and inside  we have profile images and inside we should have  
9216.66 -> so here if I say LS you can see that these are  all the IDS and we should see 43 in here so 43  
9225.06 -> so here I'm going to say CD and then 43 and inside  LS this right here is the ID of the picture itself  
9236.939 -> so if you look at this ID is the exact same  thing as this one in here and this actually  
9243.78 -> is our profile picture so if I basically say  open Dot and this brings the window Explorer  
9251.52 -> and if I select this image and then press spacebar  you can see that hooray it did work cool so let me  
9261.42 -> basically cancel out of this and out of this and  the next thing that we need to do is basically  
9269.46 -> we also have to close this and then fetch the  customers but we'll do that later but let's  
9275.1 -> basically get the profile picture back in here so  here you can see that we need the profile picture  
9282.42 -> in here and also if I close this in here also if  I click on update and what I want to show you is  
9290.88 -> so if I bring the file explorer in here let's try  and basically drag and drop so you can see that  
9299.58 -> also works so we can click but also  we can drag and drop so if I drop  
9305.04 -> you can see that profile picture updated or  uploaded my bad and if I open up the terminal  
9312.479 -> and if I press LS now we have two pictures in  here and they are both the same cool so I'm  
9322.56 -> not going to open this one because they are the  exact same pictures and you can see that this  
9327.72 -> is working if you have any questions drop me  a message otherwise catch me on the next one
9337.5 -> cool in order to see our profile picture that we  just uploaded in here and also in this card we  
9345.66 -> need to do the following so let's open up the  client.js first so here client.js and what we  
9354.54 -> need is so let's just take this right here and  we're going to say export and then cost customer  
9365.64 -> profile and then picture and then URL equals to  and here we need to pass the ID of the customer  
9378.84 -> and so on a new line I'm going to basically return  the URL like so so basically this will be the ID  
9390.359 -> and I need to remove that  and this is pretty much it  
9397.5 -> now I think I need basically oh actually not  that but I need to remove the return from here  
9404.34 -> cool so on a new line so this will gives us the  customer profile picture URL and you can even say  
9411.54 -> get in here if you want but now let's open up the  update customer dual form and in here so where we  
9421.319 -> have my drop zone so if I scroll down my drop  zone remember we have the SRC so here I'm going  
9430.92 -> to say get or actually we call it customer profile  picture URL and then pass the customer ID inside  
9443.939 -> and let's import this so insert import at the very  top and we go to go let's open up the web browser  
9453.24 -> and if I click on update check this out you  see that the picture is in here which is cool  
9460.62 -> now let's close this and also add it in  here so let's go back to IntelliJ and  
9469.2 -> that will be part of the customer card and  within customer card we have the Avatar in  
9478.14 -> here and the Avatar now will be so the  SRC for the Avatar will be so in here  
9487.439 -> customer profile picture URL and then we have  the in here I think it's just the ID so this ID  
9499.319 -> and we just pass it yes that's the ID so we just  pass it where is it Avatar I lost you so in here  
9510.72 -> ID there we go save let's go back and check this  out so this is beautiful stuff so if I click on  
9520.2 -> update you can see that now we do have the profile  pictures in place next let's go ahead and fix the  
9527.46 -> fact that when we upload a new profile picture we  should have the UI reflected on the new changes
9538.2 -> cool the last thing that I want to do is in here  when we update the customer so in here with the  
9545.819 -> new profile what we want to do is basically  invoke so we should have done this before but  
9551.28 -> that's fine so fetch customers have a look so  in here we use fetch customers like so and also  
9562.2 -> think we do close I think  we do close the model Maybe  
9569.22 -> but let's go ahead and do this so here  all we have to do really is basically  
9576.24 -> pause the fetch customer so here  we're going to say fetch customers
9582.899 -> just like that and then inside so where we  have fetch customers so we also pass it so  
9590.46 -> fetch customers equals to fetch customers  and let me put this on a new line like this  
9599.399 -> all right so in here I think this is much better  
9603.84 -> and and then things like this cool so this is  looking good now let's go to our my drop zone  
9612 -> and upon success upload we want to invoke Fetch  and then customers like this and there we go  
9623.34 -> so I'm really bad with JavaScript so here  I'm missing a bunch of semicolons and you  
9630.06 -> know with JavaScript this is actually optional  so you'll see that some places I do have like  
9634.92 -> here and other places I don't cool so this is  when a backing engineer works with JavaScript so  
9643.26 -> let's now test these changes so in here I do have  basically a new picture so if I click on update  
9651.6 -> and let me bring this picture so here female and  then two I'm going to drop the picture in here  
9660.3 -> and you can see that now it updated the picture  and we are pretty much done so here update  
9668.52 -> and you can see that the picture now has  been reflected and this is pretty much it  
9675.42 -> next let me show you something which I  forgot to change on the back end early on
9685.979 -> the last thing that I want to do is if I right  click on this picture inspect and in here so let  
9692.58 -> me put this bigger so you see so if I scroll down  you can see that we have the image source in here  
9698.58 -> and I can click on it so if I click on this you  can see that I do get gibberish basically right  
9705.899 -> so this is the byte array that we get back so  what I want actually is when someone visits  
9715.08 -> this link right here then we want to display the  actual picture well to fix that on the back end  
9722.04 -> all we have to do is within customer controller  in here so have a look so we have in here get  
9731.16 -> customer profile image and here get mapping say  comma and then inside say produces and when the  
9741.24 -> ad produces it adds a value to the endpoint URL  and here we can say a media type Dot and you can  
9752.88 -> choose PNG or jpeg it doesn't really matter there  we go indent things and let's reload the back end
9765.66 -> there we go so now we have a new customer let's  go back and if I reload this same picture in here  
9777.78 -> you can see that now we get the profile image in  here and also in here so if I basically close the  
9784.74 -> console close this we have a new customer you  can see that this other customer doesn't have a  
9792.359 -> picture so this is actually a male so let's just  say update and here I'm going to click this time  
9799.979 -> and then mail open and check this out so this is  nice if you have any questions for what we've done  
9809.34 -> in this section feel free to let me know otherwise  next I'm going to deploy all of these changes
9820.5 -> all right now let's deploy these changes  and watch our CI CD pipeline take action  
9827.16 -> for both the back end as well as the front  end so in here let's open up IntelliJ  
9833.22 -> and I'm going to commit these changes  so here I'm going to basically  
9838.74 -> commit through IntelliJ and what I'm going to do  is I'm going to say react Dash and then profile
9854.22 -> picture and then uploads there we go so commit  and we also change the back end but that's fine  
9865.5 -> which is basically these changes in here  for image JPEG value and I'm going to push
9874.319 -> and this will push straight to  Main and in here I need to rebase
9883.859 -> give it a second awesome now let's watch the  changes being deployed so in here of course  
9891.899 -> slack and this is the repo if I go to code you can  see that we have now react profile picture upload  
9902.819 -> so this will trigger the backend CI CD now you  can see that deployment Started Black profile  
9910.38 -> picture building with Maven so while this is doing  this what I'm going to show you is so this is  
9917.1 -> the back end so if I open up AWS console so in  here within the console if I go to AWS amplify
9927.84 -> and we have the full stack course and then react  
9934.26 -> and now you can see that so  basically oh I think already deployed
9944.46 -> no it hasn't right jobs failure oh wow all demos  never go according to plan so it must be like an  
9953.7 -> integration test so let's open up IntelliJ  quickly and in here so I do have so project  
9960.78 -> and let's close this go to the back end and  that's because of this so we've changed this  
9966.24 -> and we didn't update the tests so SRC test Java  and then basically the customer I.T in here  
9979.38 -> so let's just right click and I know that is  this test basically so let's just run this test
9989.28 -> so just give a second and you can see  the benefit of CI CD right so this fails  
9995.64 -> and it says so in here if I  scroll down right 500 no content
10006.5 -> right no acceptable representation that's fine  so I know exactly what it is and even IntelliJ  
10012.979 -> will tell me so intelligence telling me that  it's failing right here now remember we change  
10018.2 -> this from I think before it was application.json  the default but this now is jpeg so J and then Peg  
10027.319 -> and if I run the test again I think  this time should work fingers crossed  
10035.6 -> hooray cool let me just  basically commit this as well  
10039.8 -> and bear in mind that I'm not using pull  requests in here so fix and then test
10049.1 -> there we go commit and push
10053.54 -> and then push
10056.66 -> and let's watch it again awesome so in here so  if I refresh this you can see that we have the  
10064.399 -> new commit hopefully this time we should just  pass there we go it kicked in building with  
10070.58 -> maven and at this point basically I can even show  you so if I go to actions you can see that this  
10078.439 -> is running and deploy and you can see that still  building oh okay so you just push the docker image  
10088.04 -> right here and now it's deploying to elastic  Beanstalk so hopefully this should also pass  
10095.06 -> and you can see that all the tests actually passed  so if he reaches this stage it means that all the  
10100.34 -> tests did pass so just wait a minute or so and  hooray you can see that this was success awesome  
10109.46 -> now let's open up AWS amplify and in here you can  see that the full stack course react is running  
10118.28 -> so you can see the last deployment  which is literally just now  
10122.12 -> and to be honest this is pretty much it next  let's go ahead and test our deployed application
10134.96 -> cool let's go ahead and test this so in here um  not in localhost anymore so this is localhost and  
10142.939 -> this is the live application full stack react  and then Dot amigoscope.dev and you can try  
10149.06 -> this for yourself as well so let me just log in  with this user in here and feel free to sign up  
10155.42 -> and create an account if you have to I'm going to  log in and bad credentials okay so I think I need  
10163.1 -> to create a user so let's just say in here uh  Foo and then bar and here I'm going to say full  
10172.34 -> bar 2000 so hopefully nobody picked  this name at and then amigosco.com  
10180.26 -> let me just take this just in case  22 the password will be password  
10186.979 -> so feel free to hack my account and the mail  submit and cool so now let's go to customers  
10195.859 -> and hooray you can see that this is working  beautifully so let's in here update so we're  
10204.38 -> gonna try hold on let's if I refresh do  we get the same user so two nine eight six  
10210.8 -> refresh 2986 cool so let's just update  and in here let's just grab a picture  
10220.399 -> and Aussie two it's a male so let's just put  Amigos code in here and oops it worked but  
10232.939 -> so the customer went I don't know where because  there's so many people in here trying to use the  
10238.04 -> application so what I'm going to do is I'm going  to oh actually I was going to delete everyone but  
10245.24 -> here it works hooray we've done it so this is cool  so let's try let's see any females in here so V  
10259.16 -> male no I think yeah I think yeah no  females so basically we could just  
10266.84 -> add a picture anyways so Lorraine in here  update and we're going to add this picture  
10276.2 -> there we go and it worked you can  see that Lorraine is right here  
10284.06 -> and you can basically take this picture also  so we can basically inspect and we can grab the  
10293.84 -> URL so here I can click on it and you can see that  this is my picture and it's coming live from the  
10302.06 -> API which is under https and everything is working  beautifully awesome I might delete everyone and  
10311.06 -> add maybe some logic to say delete everyone after  I don't know maybe 24 hours or something like that  
10318.92 -> so that there's not many people so there's over a  thousand people here which is crazy cool this is  
10327.5 -> pretty much it and if you have any questions  on what we've done throughout these last few  
10334.1 -> sections as well as the exercise feel free to  let me know otherwise catch me on the next one
10344.3 -> okey dokey if you enjoyed this video literally  just smash the like button comment down below  
10349.64 -> let me know what other things that you want to  see next and I'm going to leave a coupon code  
10355.34 -> in the description of this video so that  you can take benefit and you know learn  
10361.1 -> the full-time professional course that I have  for you which is a course that is changing  
10366.439 -> lives many people are managing to secure jobs and  people that work for companies meet developers  
10373.04 -> senior developers all are benefiting from this  course so this is a course that you won't find  
10380.6 -> anywhere else apart from a vehicle's code this is  pretty much it and I'll see you on the next one

Source: https://www.youtube.com/watch?v=9i1gQ7w2V24