From 6eec5ec09dee15529060617e760641981b476f6e Mon Sep 17 00:00:00 2001 From: biswajit Date: Mon, 2 Oct 2023 17:13:45 +0530 Subject: [PATCH] Biswajit| product service with 7 apis --- .gradle/8.2/checksums/checksums.lock | Bin 0 -> 17 bytes .../dependencies-accessors.lock | Bin 0 -> 17 bytes .../8.2/dependencies-accessors/gc.properties | 0 .../8.2/executionHistory/executionHistory.bin | Bin 0 -> 65258 bytes .../executionHistory/executionHistory.lock | Bin 0 -> 17 bytes .gradle/8.2/fileChanges/last-build.bin | Bin 0 -> 1 bytes .gradle/8.2/fileHashes/fileHashes.bin | Bin 0 -> 21347 bytes .gradle/8.2/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .../8.2/fileHashes/resourceHashesCache.bin | Bin 0 -> 19279 bytes .gradle/8.2/gc.properties | 0 .../buildOutputCleanup.lock | Bin 0 -> 17 bytes .gradle/buildOutputCleanup/cache.properties | 2 + .gradle/buildOutputCleanup/outputFiles.bin | Bin 0 -> 19073 bytes .gradle/file-system.probe | Bin 0 -> 8 bytes .gradle/vcs-1/gc.properties | 0 .jpb/jpb-settings.xml | 13 - .mvn/wrapper/maven-wrapper.jar | Bin 62547 -> 0 bytes .mvn/wrapper/maven-wrapper.properties | 2 - README.md | 2 + backend module.json | 103 ++++++ build.gradle | 42 +++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63375 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 248 ++++++++++++++ gradlew.bat | 92 ++++++ mvnw | 308 ------------------ mvnw.cmd | 205 ------------ pom.xml | 87 ----- queries.sql | 82 ----- settings.gradle | 1 + .../ProductServiceApplication.java | 13 + .../controller/CategoryController.java | 42 +++ .../controller/ProductController.java | 52 +++ .../ecomm/productservice/dto/CategoryDto.java | 16 + .../ecomm/productservice/dto/ProductDto.java | 25 ++ .../productservice/exception/ErrorCode.java | 6 + .../productservice/exception/ErrorDto.java | 11 + .../exception/ProductControllerAdvice.java | 27 ++ .../exception/ProductNotFoundException.java | 12 + .../ecomm/productservice/model/Category.java | 44 +++ .../ecomm/productservice/model/Currency.java | 6 + .../ecomm/productservice/model/Price.java | 42 +++ .../ecomm/productservice/model/Product.java | 42 +++ .../repository/CategoryRepository.java | 14 + .../repository/PriceRepository.java | 13 + .../repository/ProductRepository.java | 23 ++ .../service/CategoryService.java | 13 + .../service/CategoryServiceImpl.java | 50 +++ .../service/FakeStoreProductService.java | 75 +++++ .../service/ProductService.java | 21 ++ .../service/SelfManagedProductService.java | 115 +++++++ .../thirdparty/FakeStoreClient.java | 70 ++++ .../thirdparty/ThirdPartyProductDto.java | 18 + .../ProductserviceApplication.java | 119 ------- .../controllers/CategoryController.java | 49 --- .../controllers/ProductController.java | 73 ----- .../productservice/dtos/CategoryDto.java | 14 - .../productservice/dtos/ExceptionDto.java | 17 - .../dtos/GenericProductDto.java | 16 - .../dtos/GetProductTitlesRequestDto.java | 12 - .../naman/productservice/dtos/ProductDto.java | 25 -- .../exceptions/ControllerAdvices.java | 32 -- .../exceptions/NotFoundException.java | 12 - .../inheritancedemo/joinedtable/Mentor.java | 14 - .../joinedtable/MentorRepository.java | 11 - .../inheritancedemo/joinedtable/Student.java | 15 - .../inheritancedemo/joinedtable/TA.java | 14 - .../inheritancedemo/joinedtable/User.java | 19 -- .../joinedtable/UserRepository.java | 12 - .../mappedsuperclass/Mentor.java | 12 - .../mappedsuperclass/Student.java | 13 - .../inheritancedemo/mappedsuperclass/TA.java | 12 - .../mappedsuperclass/User.java | 19 -- .../inheritancedemo/singletable/Mentor.java | 14 - .../singletable/MentorRepository.java | 12 - .../inheritancedemo/singletable/Student.java | 15 - .../inheritancedemo/singletable/TA.java | 14 - .../inheritancedemo/singletable/User.java | 22 -- .../singletable/UserRepository.java | 13 - .../inheritancedemo/tableperclass/Mentor.java | 13 - .../tableperclass/MentorRepository.java | 12 - .../tableperclass/Student.java | 14 - .../inheritancedemo/tableperclass/TA.java | 13 - .../inheritancedemo/tableperclass/User.java | 21 -- .../tableperclass/UserRepository.java | 13 - .../productservice/models/BaseModel.java | 16 - .../naman/productservice/models/Category.java | 36 -- .../naman/productservice/models/Order.java | 21 -- .../naman/productservice/models/Price.java | 17 - .../naman/productservice/models/Product.java | 34 -- .../repositories/CategoryRepository.java | 19 -- .../repositories/CustomQueries.java | 6 - .../repositories/PriceRepository.java | 8 - .../repositories/ProductRepository.java | 47 --- .../services/CategoryService.java | 10 - .../services/CategoryServiceImpl.java | 79 ----- .../services/FakeStoreProductService.java | 63 ---- .../services/ProductService.java | 17 - .../services/SelfProductServiceImpl.java | 42 --- .../fakestore/FakeStoreProductDto.java | 18 - .../FakeStoryProductServiceClient.java | 97 ------ src/main/resources/application.properties | 20 -- src/main/resources/application.yml | 27 ++ .../resources/db/migration/V1__init_db.sql | 164 ---------- ...d_something_add_column_inventory_count.sql | 11 - ...ManagedProductServiceApplicationTests.java | 13 + .../ProductControllerIntegrationTest.java | 44 +++ .../ProductserviceApplicationTests.java | 13 - .../dev/naman/productservice/RandomTest.java | 17 - .../controllers/ProductControllerTest.java | 70 ---- .../FakeStoryProductServiceClientTest.java | 27 -- 111 files changed, 1331 insertions(+), 2235 deletions(-) create mode 100644 .gradle/8.2/checksums/checksums.lock create mode 100644 .gradle/8.2/dependencies-accessors/dependencies-accessors.lock rename src/main/resources/db/migration/V3__go_away_something.sql => .gradle/8.2/dependencies-accessors/gc.properties (100%) create mode 100644 .gradle/8.2/executionHistory/executionHistory.bin create mode 100644 .gradle/8.2/executionHistory/executionHistory.lock create mode 100644 .gradle/8.2/fileChanges/last-build.bin create mode 100644 .gradle/8.2/fileHashes/fileHashes.bin create mode 100644 .gradle/8.2/fileHashes/fileHashes.lock create mode 100644 .gradle/8.2/fileHashes/resourceHashesCache.bin create mode 100644 .gradle/8.2/gc.properties create mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock create mode 100644 .gradle/buildOutputCleanup/cache.properties create mode 100644 .gradle/buildOutputCleanup/outputFiles.bin create mode 100644 .gradle/file-system.probe create mode 100644 .gradle/vcs-1/gc.properties delete mode 100644 .jpb/jpb-settings.xml delete mode 100644 .mvn/wrapper/maven-wrapper.jar delete mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100644 README.md create mode 100644 backend module.json create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat delete mode 100755 mvnw delete mode 100644 mvnw.cmd delete mode 100644 pom.xml delete mode 100644 queries.sql create mode 100644 settings.gradle create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/ProductServiceApplication.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/controller/CategoryController.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/controller/ProductController.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/dto/CategoryDto.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/dto/ProductDto.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/exception/ErrorCode.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/exception/ErrorDto.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/exception/ProductControllerAdvice.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/exception/ProductNotFoundException.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/model/Category.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/model/Currency.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/model/Price.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/model/Product.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/repository/CategoryRepository.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/repository/PriceRepository.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/repository/ProductRepository.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/service/CategoryService.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/service/CategoryServiceImpl.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/service/FakeStoreProductService.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/service/ProductService.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/service/SelfManagedProductService.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/thirdparty/FakeStoreClient.java create mode 100644 src/main/java/dev/biswajit/ecomm/productservice/thirdparty/ThirdPartyProductDto.java delete mode 100644 src/main/java/dev/naman/productservice/ProductserviceApplication.java delete mode 100644 src/main/java/dev/naman/productservice/controllers/CategoryController.java delete mode 100644 src/main/java/dev/naman/productservice/controllers/ProductController.java delete mode 100644 src/main/java/dev/naman/productservice/dtos/CategoryDto.java delete mode 100644 src/main/java/dev/naman/productservice/dtos/ExceptionDto.java delete mode 100644 src/main/java/dev/naman/productservice/dtos/GenericProductDto.java delete mode 100644 src/main/java/dev/naman/productservice/dtos/GetProductTitlesRequestDto.java delete mode 100644 src/main/java/dev/naman/productservice/dtos/ProductDto.java delete mode 100644 src/main/java/dev/naman/productservice/exceptions/ControllerAdvices.java delete mode 100644 src/main/java/dev/naman/productservice/exceptions/NotFoundException.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/Mentor.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/MentorRepository.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/Student.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/TA.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/User.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/UserRepository.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/Mentor.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/Student.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/TA.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/User.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/singletable/Mentor.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/singletable/MentorRepository.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/singletable/Student.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/singletable/TA.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/singletable/User.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/singletable/UserRepository.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/Mentor.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/MentorRepository.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/Student.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/TA.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/User.java delete mode 100644 src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/UserRepository.java delete mode 100644 src/main/java/dev/naman/productservice/models/BaseModel.java delete mode 100644 src/main/java/dev/naman/productservice/models/Category.java delete mode 100644 src/main/java/dev/naman/productservice/models/Order.java delete mode 100644 src/main/java/dev/naman/productservice/models/Price.java delete mode 100644 src/main/java/dev/naman/productservice/models/Product.java delete mode 100644 src/main/java/dev/naman/productservice/repositories/CategoryRepository.java delete mode 100644 src/main/java/dev/naman/productservice/repositories/CustomQueries.java delete mode 100644 src/main/java/dev/naman/productservice/repositories/PriceRepository.java delete mode 100644 src/main/java/dev/naman/productservice/repositories/ProductRepository.java delete mode 100644 src/main/java/dev/naman/productservice/services/CategoryService.java delete mode 100644 src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java delete mode 100644 src/main/java/dev/naman/productservice/services/FakeStoreProductService.java delete mode 100644 src/main/java/dev/naman/productservice/services/ProductService.java delete mode 100644 src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java delete mode 100644 src/main/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoreProductDto.java delete mode 100644 src/main/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoryProductServiceClient.java delete mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/application.yml delete mode 100644 src/main/resources/db/migration/V1__init_db.sql delete mode 100644 src/main/resources/db/migration/V2__add_something_add_column_inventory_count.sql create mode 100644 src/test/java/dev/biswajit/ecomm/productservice/SelfManagedProductServiceApplicationTests.java create mode 100644 src/test/java/dev/biswajit/ecomm/productservice/productcontroller/ProductControllerIntegrationTest.java delete mode 100644 src/test/java/dev/naman/productservice/ProductserviceApplicationTests.java delete mode 100644 src/test/java/dev/naman/productservice/RandomTest.java delete mode 100644 src/test/java/dev/naman/productservice/controllers/ProductControllerTest.java delete mode 100644 src/test/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoryProductServiceClientTest.java diff --git a/.gradle/8.2/checksums/checksums.lock b/.gradle/8.2/checksums/checksums.lock new file mode 100644 index 0000000000000000000000000000000000000000..66e521b7fc087675f5a908da84efdc2efd9dc0a8 GIT binary patch literal 17 ScmZSnQJS4yrnFas0SW*yumi*Z literal 0 HcmV?d00001 diff --git a/.gradle/8.2/dependencies-accessors/dependencies-accessors.lock b/.gradle/8.2/dependencies-accessors/dependencies-accessors.lock new file mode 100644 index 0000000000000000000000000000000000000000..f44eed4e2ab729f3430b4c09cd4a78a36201c020 GIT binary patch literal 17 TcmZQx^{3iXSnb+U1}FdkG{yuX literal 0 HcmV?d00001 diff --git a/src/main/resources/db/migration/V3__go_away_something.sql b/.gradle/8.2/dependencies-accessors/gc.properties similarity index 100% rename from src/main/resources/db/migration/V3__go_away_something.sql rename to .gradle/8.2/dependencies-accessors/gc.properties diff --git a/.gradle/8.2/executionHistory/executionHistory.bin b/.gradle/8.2/executionHistory/executionHistory.bin new file mode 100644 index 0000000000000000000000000000000000000000..3c64bf954018bb7b465eed8ecd0e0ee8bc97ab0b GIT binary patch literal 65258 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 z%0A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 ZsK?st;JC76)r6g~0Mf{|{)h=CA+& literal 0 HcmV?d00001 diff --git a/.gradle/8.2/executionHistory/executionHistory.lock b/.gradle/8.2/executionHistory/executionHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..b68addd421a6da126068919049f0e9d3ef4f8917 GIT binary patch literal 17 UcmZS9{*XQG#*}r_86bcI06QB5*#H0l literal 0 HcmV?d00001 diff --git a/.gradle/8.2/fileChanges/last-build.bin b/.gradle/8.2/fileChanges/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/.gradle/8.2/fileHashes/fileHashes.bin b/.gradle/8.2/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..8242661339c37748a75aec1b2761c4fc1a17aa62 GIT binary patch literal 21347 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 BnSB5N literal 0 HcmV?d00001 diff --git a/.gradle/8.2/fileHashes/fileHashes.lock b/.gradle/8.2/fileHashes/fileHashes.lock new file mode 100644 index 0000000000000000000000000000000000000000..bae14ad694d00e38e4afe01adec3d8ce431511b1 GIT binary patch literal 17 TcmZSfnCGcwr|7YY0RkcbA)5mR literal 0 HcmV?d00001 diff --git a/.gradle/8.2/fileHashes/resourceHashesCache.bin b/.gradle/8.2/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000000000000000000000000000000000000..0280fdc153090aee754bdcf18b927a9a1662a03a GIT binary patch literal 19279 zcmeI(`A^el0LSq!RgemWR!~9ZP>ABeAsS!`B9W_zMNqVcsK}MdR>mPCnpozIMnR%=X1Al^z+4@3nT34$5{IU;PSI0jK!Ft8~QD@~tgMxH;w#C)2x{pQ_Io~Ex~n{Ob; z*$8#y!F_&A{(Olm2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00h1jf#}g6GSTp3 zY!>kJ7nWHZ=V3m2G4?(?+T`D%4w5;>=q_T|wQX~I8C zElIbdeMRz>V?pO~iL+Qhd!&e`%|G~dDLFrq_KlA`x|NsgQ%P^9J*~1hyQn)qm-J!U zGpsuA=hyN*4L!8<|9+uHF1lNAk@VNJE6SHhpWS&igPe1dcKXh7yzdO3;S~Z9fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00h34fc_=`+tH^;{}jq!Hfr5+Vr=YWN@tgbt`(!v{>w$gTDe7L^rpYUQ&lB?Vfh2> zLeudsPtu1=_wPHKh(Pw{%x+hQC>USkzMcu?oJqzs)K(!lxq?b(yPDiVvLy1E~xr`hw(#h zM8h90j6K3Gemw5sHFKKKqU&1o(vPaRJa&Fi>)Ll57iWwGrt%|FhZxOgYKkcO!(QX;)}`7aA_I#4zc!Y=;1?As#S z7GGa4S6PjejQf{e7!^g$wO!SqR#!Q-KHDkM--9s5BUIowX(;h{kLUZO0)@|+d+egk z$lotemOe1eG{ixy>)69CTu(*Z@bn%G>h3r3y*?*Kf9JxOZ}H&^$4k?1e&}4Yx%Kd6 a(SCN3Y^~NrskFR9*C$+Ea?1Rbe(?#4G;A%%vCcftgT!uP5J>zEobBa%-t+97&+SY? zs23&a5YtEg^b#uwKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1pXI+D(OX(^2?}8 zvQmqM^+K#$AT5?R8MVsRcu7*eY_8}34=%Vb2ZN7vMbzJOzvxP~Xch~N+$~Mq+p3kS z*?DW?)O)#K8}j7_430z8-*CS*vGnD@7psfrZ|6RwEAT|GZ#_->pK^cx$}6tg+~w47 za1UKM>d|;@()*+itAYDy#gQG&b=qdRTkPCl`|FOGHXn@0-KygrxgWDe8vAe4{zC5G z)!F0a@zPV&qugU(-}-M}@-3k``P_flYE-JAm{JzP+{HcKS-NT9fnG;*in%AAEDI;U zjTTei!hOy}Sw!Ky`%LcU827mkJ68DaoXw-(t>#|P<8hANTh&E(k-jdHiva_4U$6uI&>d_n*M5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|nE3)_(j(53&RMB5 l^^x;Ok;05BnLT0pU4K(Dd-wFonaxSRE3?V}?yjlHzX7UOvN-?% literal 0 HcmV?d00001 diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe new file mode 100644 index 0000000000000000000000000000000000000000..991c5a2e704630d70cb8e772871d08de9b5e00e4 GIT binary patch literal 8 PcmZQzVC?!}(AEk72%!SE literal 0 HcmV?d00001 diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.jpb/jpb-settings.xml b/.jpb/jpb-settings.xml deleted file mode 100644 index c6d2fb3..0000000 --- a/.jpb/jpb-settings.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index cb28b0e37c7d206feb564310fdeec0927af4123a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62547 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 A?*IS* diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 2e76e18..0000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/README.md b/README.md new file mode 100644 index 0000000..75d4d6c --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +### start mysql container +docker run -p 3306:3306 --name my-mysql -e MYSQL_ROOT_PASSWORD=secret -v $HOME/mysql-data:/var/lib/mysql -d mysql:latest \ No newline at end of file diff --git a/backend module.json b/backend module.json new file mode 100644 index 0000000..476cbc8 --- /dev/null +++ b/backend module.json @@ -0,0 +1,103 @@ +{ + "client": "Thunder Client", + "collectionName": "backend module", + "dateExported": "2023-09-23T11:13:46.818Z", + "version": "1.1", + "folders": [], + "requests": [ + { + "_id": "b6e1c5dd-e2cb-4922-b1df-4b8027ff2093", + "colId": "94371b6c-0274-4884-a2b4-e7c59641ae59", + "containerId": "", + "name": "get product", + "url": "http://localhost:8080/products/2", + "method": "GET", + "sortNum": 10000, + "created": "2023-09-07T13:35:25.110Z", + "modified": "2023-09-19T11:20:44.240Z", + "headers": [], + "params": [], + "tests": [] + }, + { + "_id": "b170e220-6a4e-48c2-8b73-83bffe820c48", + "colId": "94371b6c-0274-4884-a2b4-e7c59641ae59", + "containerId": "", + "name": "update product", + "url": "http://localhost:8080/products/1", + "method": "PUT", + "sortNum": 20000, + "created": "2023-09-07T13:50:26.018Z", + "modified": "2023-09-19T11:37:43.927Z", + "headers": [], + "params": [], + "body": { + "type": "json", + "raw": "{\n \"title\": \"samsung galaxy 2\",\n \"price\": 25000.50,\n \"description\": \"lorem ipsum set\",\n \"image\": \"https://i.pravatar.cc\",\n \"category\": \"mobile\"\n}", + "form": [] + }, + "tests": [] + }, + { + "_id": "877bcd65-e71b-4beb-81fd-6de44c07e228", + "colId": "94371b6c-0274-4884-a2b4-e7c59641ae59", + "containerId": "", + "name": "create product", + "url": "http://localhost:8080/products/", + "method": "POST", + "sortNum": 30000, + "created": "2023-09-19T10:39:37.695Z", + "modified": "2023-09-23T10:43:05.370Z", + "headers": [], + "params": [], + "body": { + "type": "json", + "raw": "{\n \"title\": \"macbook m2\",\n \"price\": 195000.00,\n \"description\": \"lorem ipsum set\",\n \"image\": \"https://i.pravatar.cc\",\n \"category\": \"laptop\"\n}", + "form": [] + }, + "tests": [] + }, + { + "_id": "7b3b931e-8358-42b1-9e18-bbadb883000e", + "colId": "94371b6c-0274-4884-a2b4-e7c59641ae59", + "containerId": "", + "name": "delete product", + "url": "http://localhost:8080/products/52", + "method": "DELETE", + "sortNum": 40000, + "created": "2023-09-19T10:39:53.512Z", + "modified": "2023-09-23T10:44:50.188Z", + "headers": [], + "params": [], + "tests": [] + }, + { + "_id": "0344dfd2-d823-4ae7-9b9b-6c42888ea2ba", + "colId": "94371b6c-0274-4884-a2b4-e7c59641ae59", + "containerId": "", + "name": "get all product", + "url": "http://localhost:8080/products/", + "method": "GET", + "sortNum": 50000, + "created": "2023-09-19T10:40:40.504Z", + "modified": "2023-09-19T10:40:40.504Z", + "headers": [], + "params": [], + "tests": [] + }, + { + "_id": "a497f3d5-ef54-454f-a8c3-356dfcac61ad", + "colId": "94371b6c-0274-4884-a2b4-e7c59641ae59", + "containerId": "", + "name": "get all products of a category", + "url": "http://localhost:8080/categories/computer/products", + "method": "GET", + "sortNum": 60000, + "created": "2023-09-22T13:35:37.939Z", + "modified": "2023-09-22T16:07:23.326Z", + "headers": [], + "params": [], + "tests": [] + } + ] +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..f31640b --- /dev/null +++ b/build.gradle @@ -0,0 +1,42 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.1.3' + id 'io.spring.dependency-management' version '1.1.3' +} + +group = 'dev.biswajit.ecomm' +version = '0.0.1-SNAPSHOT' + +java { + sourceCompatibility = '17' +} + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-webflux' + compileOnly 'org.projectlombok:lombok' + implementation 'mysql:mysql-connector-java:8.0.26' + developmentOnly 'org.springframework.boot:spring-boot-devtools' + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'io.projectreactor:reactor-test' +} + +tasks.named('test') { + useJUnitPlatform() +} + +tasks.withType(Test) { + enabled=false +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..033e24c4cdf41af1ab109bc7f253b2b887023340 GIT binary patch literal 63375 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≫L+crb^Bz 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..6689b85 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/mvnw b/mvnw deleted file mode 100755 index 66df285..0000000 --- a/mvnw +++ /dev/null @@ -1,308 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.2.0 -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /usr/local/etc/mavenrc ] ; then - . /usr/local/etc/mavenrc - fi - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "$(uname)" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME - else - JAVA_HOME="/Library/Java/Home"; export JAVA_HOME - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=$(java-config --jre-home) - fi -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=$(cygpath --unix "$JAVA_HOME") - [ -n "$CLASSPATH" ] && - CLASSPATH=$(cygpath --path --unix "$CLASSPATH") -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && - JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="$(which javac)" - if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=$(which readlink) - if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then - if $darwin ; then - javaHome="$(dirname "\"$javaExecutable\"")" - javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" - else - javaExecutable="$(readlink -f "\"$javaExecutable\"")" - fi - javaHome="$(dirname "\"$javaExecutable\"")" - javaHome=$(expr "$javaHome" : '\(.*\)/bin') - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=$(cd "$wdir/.." || exit 1; pwd) - fi - # end of workaround - done - printf '%s' "$(cd "$basedir" || exit 1; pwd)" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - # Remove \r in case we run on Windows within Git Bash - # and check out the repository with auto CRLF management - # enabled. Otherwise, we may read lines that are delimited with - # \r\n and produce $'-Xarg\r' rather than -Xarg due to word - # splitting rules. - tr -s '\r\n' ' ' < "$1" - fi -} - -log() { - if [ "$MVNW_VERBOSE" = true ]; then - printf '%s\n' "$1" - fi -} - -BASE_DIR=$(find_maven_basedir "$(dirname "$0")") -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR -log "$MAVEN_PROJECTBASEDIR" - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" -if [ -r "$wrapperJarPath" ]; then - log "Found $wrapperJarPath" -else - log "Couldn't find $wrapperJarPath, downloading it ..." - - if [ -n "$MVNW_REPOURL" ]; then - wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - else - wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - fi - while IFS="=" read -r key value; do - # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) - safeValue=$(echo "$value" | tr -d '\r') - case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; - esac - done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" - log "Downloading from: $wrapperUrl" - - if $cygwin; then - wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") - fi - - if command -v wget > /dev/null; then - log "Found wget ... using wget" - [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - else - wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - log "Found curl ... using curl" - [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" - else - curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" - fi - else - log "Falling back to using Java to download" - javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" - javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaSource=$(cygpath --path --windows "$javaSource") - javaClass=$(cygpath --path --windows "$javaClass") - fi - if [ -e "$javaSource" ]; then - if [ ! -e "$javaClass" ]; then - log " - Compiling MavenWrapperDownloader.java ..." - ("$JAVA_HOME/bin/javac" "$javaSource") - fi - if [ -e "$javaClass" ]; then - log " - Running MavenWrapperDownloader.java ..." - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -# If specified, validate the SHA-256 sum of the Maven wrapper jar file -wrapperSha256Sum="" -while IFS="=" read -r key value; do - case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; - esac -done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" -if [ -n "$wrapperSha256Sum" ]; then - wrapperSha256Result=false - if command -v sha256sum > /dev/null; then - if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then - wrapperSha256Result=true - fi - elif command -v shasum > /dev/null; then - if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then - wrapperSha256Result=true - fi - else - echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." - echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." - exit 1 - fi - if [ $wrapperSha256Result = false ]; then - echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 - echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 - echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 - exit 1 - fi -fi - -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") - [ -n "$CLASSPATH" ] && - CLASSPATH=$(cygpath --path --windows "$CLASSPATH") - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -# shellcheck disable=SC2086 # safe args -exec "$JAVACMD" \ - $MAVEN_OPTS \ - $MAVEN_DEBUG_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100644 index 95ba6f5..0000000 --- a/mvnw.cmd +++ /dev/null @@ -1,205 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.2.0 -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* -if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %WRAPPER_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file -SET WRAPPER_SHA_256_SUM="" -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B -) -IF NOT %WRAPPER_SHA_256_SUM%=="" ( - powershell -Command "&{"^ - "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ - "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ - " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ - " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ - " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ - " exit 1;"^ - "}"^ - "}" - if ERRORLEVEL 1 goto error -) - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% ^ - %JVM_CONFIG_MAVEN_PROPS% ^ - %MAVEN_OPTS% ^ - %MAVEN_DEBUG_OPTS% ^ - -classpath %WRAPPER_JAR% ^ - "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ - %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" -if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%"=="on" pause - -if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% - -cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 19a39f7..0000000 --- a/pom.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.1.3 - - - dev.naman - productservice - 0.0.1-SNAPSHOT - productservice - productservice - - 17 - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.projectlombok - lombok - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-actuator - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - com.mysql - mysql-connector-j - runtime - - - - org.flywaydb - flyway-mysql - 9.22.2 - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - - - diff --git a/queries.sql b/queries.sql deleted file mode 100644 index 50d245f..0000000 --- a/queries.sql +++ /dev/null @@ -1,82 +0,0 @@ -select u1_0.id, u1_0.clazz_, u1_0.email, u1_0.name, u1_0.average_rating, u1_0.attendance, u1_0.psp -from (select id, email, name, null as average_rating, null as attendance, null as psp, 0 as clazz_ - from tpc_user - union all - select id, email, name, average_rating, null as attendance, null as psp, 1 as clazz_ - from tpc_mentor - union all - select id, email, name, null as average_rating, attendance, psp, 2 as clazz_ - from tpc_student - union all - select id, email, name, average_rating, null as attendance, null as psp, 3 as clazz_ - from tpc_ta) u1_0 - - -select c1_0.id, - c1_0.name, - p1_0.category_id, - p1_0.id, - p1_0.description, - p1_0.image, - p1_0.price, - p1_0.title -from category c1_0 - left join product p1_0 on c1_0.id = p1_0.category_id -where c1_0.id = ? - -select c1_0.id, c1_0.name -from category c1_0 -where c1_0.id = ? - -select p1_0.category, - p1_0.id, - p1_0.description, - p1_0.image, - p2_0.id, - p2_0.currency, - p2_0.price, - p1_0.title -from product p1_0 - left join price p2_0 on p2_0.id = p1_0.price_id -where p1_0.category = ? - -select p1_0.category, - p1_0.id, - p1_0.description, - p1_0.image, - p2_0.id, - p2_0.currency, - p2_0.price, - p1_0.title -from product p1_0 - left join price p2_0 on p2_0.id = p1_0.price_id -where p1_0.category = ? - -select c1_0.id, - c1_0.name, - p1_0.category, - p1_0.id, - p1_0.description, - p1_0.image, - p2_0.id, - p2_0.currency, - p2_0.price, - p1_0.title -from category c1_0 - left join product p1_0 on c1_0.id = p1_0.category - left join price p2_0 on p2_0.id = p1_0.price_id -where c1_0.id = ? Hibernate: -select c1_0.id, - c1_0.name, - p1_0.category, - p1_0.id, - p1_0.description, - p1_0.image, - p2_0.id, - p2_0.currency, - p2_0.price, - p1_0.title -from category c1_0 - left join product p1_0 on c1_0.id = p1_0.category - left join price p2_0 on p2_0.id = p1_0.price_id -where c1_0.id = ? \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..b489814 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'productservice' diff --git a/src/main/java/dev/biswajit/ecomm/productservice/ProductServiceApplication.java b/src/main/java/dev/biswajit/ecomm/productservice/ProductServiceApplication.java new file mode 100644 index 0000000..655b18c --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/ProductServiceApplication.java @@ -0,0 +1,13 @@ +package dev.biswajit.ecomm.productservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProductServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(ProductServiceApplication.class, args); + } + +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/controller/CategoryController.java b/src/main/java/dev/biswajit/ecomm/productservice/controller/CategoryController.java new file mode 100644 index 0000000..715a489 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/controller/CategoryController.java @@ -0,0 +1,42 @@ +package dev.biswajit.ecomm.productservice.controller; + +import dev.biswajit.ecomm.productservice.dto.CategoryDto; +import dev.biswajit.ecomm.productservice.dto.ProductDto; +import dev.biswajit.ecomm.productservice.service.CategoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.List; + +@RestController +@RequestMapping("/categories") +public class CategoryController { + + private final CategoryService categoryService; + + public CategoryController(@Autowired CategoryService categoryService) { + this.categoryService = categoryService; + } + + @GetMapping(value = "/") + Flux getAllCategories() { + + return categoryService.allCategories() + .flatMapMany(Flux::fromIterable) + .flatMap(it -> Mono.just(CategoryDto.builder() + .categoryId(it.getId()) + .title(it.getTitle()) + .build())); + } + + @GetMapping("/{title}/products") + public Mono> getProductsIn(@PathVariable String title) { + return categoryService.findProductsByCategory(title); + } + +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/controller/ProductController.java b/src/main/java/dev/biswajit/ecomm/productservice/controller/ProductController.java new file mode 100644 index 0000000..af39adf --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/controller/ProductController.java @@ -0,0 +1,52 @@ +package dev.biswajit.ecomm.productservice.controller; + +import dev.biswajit.ecomm.productservice.dto.ProductDto; +import dev.biswajit.ecomm.productservice.exception.ErrorDto; +import dev.biswajit.ecomm.productservice.exception.ProductNotFoundException; +import dev.biswajit.ecomm.productservice.service.ProductService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.UUID; + +import static dev.biswajit.ecomm.productservice.exception.ErrorCode.PRODUCT_NOT_FOUND; + +@RestController +@RequestMapping("/products") +public class ProductController { + + private final ProductService productService; + + public ProductController(ProductService productService) { + this.productService = productService; + } + + @GetMapping("/") + public Mono> getAll() { + return productService.allProducts(); + } + + @GetMapping("/{id}") + public Mono getBy(@PathVariable("id") Long productId) throws ProductNotFoundException { + return productService.productBy(productId); + } + + @PostMapping("/") + @ResponseStatus(code = HttpStatus.CREATED) + public Mono add(@RequestBody ProductDto newProduct) { + return productService.add(newProduct); + } + + @PutMapping("/{id}") + public Mono updateBy(@PathVariable("id") Long id, @RequestBody ProductDto updateProductDto) throws ProductNotFoundException { + return productService.updateBy(id, updateProductDto); + } + + @DeleteMapping("/{id}") + public Mono deleteBy(@PathVariable Long id) throws ProductNotFoundException { + return productService.deleteBy(id); + } +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/dto/CategoryDto.java b/src/main/java/dev/biswajit/ecomm/productservice/dto/CategoryDto.java new file mode 100644 index 0000000..08af6cc --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/dto/CategoryDto.java @@ -0,0 +1,16 @@ +package dev.biswajit.ecomm.productservice.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; + +import java.util.UUID; + +@Builder +public class CategoryDto { + @JsonProperty(value = "id") + private UUID categoryId; + @JsonProperty(value = "title") + @JsonInclude(JsonInclude.Include.NON_NULL) + private String title; +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/dto/ProductDto.java b/src/main/java/dev/biswajit/ecomm/productservice/dto/ProductDto.java new file mode 100644 index 0000000..c4c6899 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/dto/ProductDto.java @@ -0,0 +1,25 @@ +package dev.biswajit.ecomm.productservice.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProductDto { + private Long id; + private String title; + private String price; + private String category; + @JsonInclude(JsonInclude.Include.NON_NULL) + private String description; + @JsonProperty("image") + private String imageUrl; +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/exception/ErrorCode.java b/src/main/java/dev/biswajit/ecomm/productservice/exception/ErrorCode.java new file mode 100644 index 0000000..932b774 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/exception/ErrorCode.java @@ -0,0 +1,6 @@ +package dev.biswajit.ecomm.productservice.exception; + +public enum ErrorCode { + PRODUCT_NOT_FOUND, + INTERNAL_SERVER_ERROR +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/exception/ErrorDto.java b/src/main/java/dev/biswajit/ecomm/productservice/exception/ErrorDto.java new file mode 100644 index 0000000..7600804 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/exception/ErrorDto.java @@ -0,0 +1,11 @@ +package dev.biswajit.ecomm.productservice.exception; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +@JsonIgnoreProperties(ignoreUnknown = true) +@Data +public class ErrorDto { + private final ErrorCode code; + private final String message; +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/exception/ProductControllerAdvice.java b/src/main/java/dev/biswajit/ecomm/productservice/exception/ProductControllerAdvice.java new file mode 100644 index 0000000..bb3d9a8 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/exception/ProductControllerAdvice.java @@ -0,0 +1,27 @@ +package dev.biswajit.ecomm.productservice.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import reactor.core.publisher.Mono; + +import static dev.biswajit.ecomm.productservice.exception.ErrorCode.INTERNAL_SERVER_ERROR; +import static dev.biswajit.ecomm.productservice.exception.ErrorCode.PRODUCT_NOT_FOUND; + +@ControllerAdvice +public class ProductControllerAdvice { + @ExceptionHandler(value = ProductNotFoundException.class) + private ResponseEntity> productNotFoundException(ProductNotFoundException exception) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Mono.just(new ErrorDto(PRODUCT_NOT_FOUND, exception.getMessage()))); + } + + @ExceptionHandler + private ResponseEntity> handleDefaultException(Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Mono.just(new ErrorDto(INTERNAL_SERVER_ERROR, e.getMessage()))); + } + + +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/exception/ProductNotFoundException.java b/src/main/java/dev/biswajit/ecomm/productservice/exception/ProductNotFoundException.java new file mode 100644 index 0000000..83fa634 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/exception/ProductNotFoundException.java @@ -0,0 +1,12 @@ +package dev.biswajit.ecomm.productservice.exception; + +public class ProductNotFoundException extends Exception{ + private ProductNotFoundException(String message) { + super(message); + } + + public static ProductNotFoundException with(String message) { + return new ProductNotFoundException(message); + } + +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/model/Category.java b/src/main/java/dev/biswajit/ecomm/productservice/model/Category.java new file mode 100644 index 0000000..2f523a8 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/model/Category.java @@ -0,0 +1,44 @@ +package dev.biswajit.ecomm.productservice.model; + +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; + +import java.util.Objects; +import java.util.Set; +import java.util.UUID; + +@NoArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "CATEGORIES") +public class Category { + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; + + private String title; + + @OneToMany(mappedBy = "category", fetch = FetchType.LAZY) + @Fetch(FetchMode.JOIN) + private Set products; + + public Category(String category) { + this.title = category; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Category category = (Category) o; + return Objects.equals(title, category.title); + } + + @Override + public int hashCode() { + return Objects.hash(title); + } +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/model/Currency.java b/src/main/java/dev/biswajit/ecomm/productservice/model/Currency.java new file mode 100644 index 0000000..68246c3 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/model/Currency.java @@ -0,0 +1,6 @@ +package dev.biswajit.ecomm.productservice.model; + +public enum Currency { + RUPEE, + DOLLAR +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/model/Price.java b/src/main/java/dev/biswajit/ecomm/productservice/model/Price.java new file mode 100644 index 0000000..ba8cc40 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/model/Price.java @@ -0,0 +1,42 @@ +package dev.biswajit.ecomm.productservice.model; + +import jakarta.persistence.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Objects; +import java.util.UUID; + +@Data +@NoArgsConstructor +@Entity +@Table(name = "PRICES") +public class Price { + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; + + private Double value; + + @Enumerated(value = EnumType.STRING) + private Currency currency; + + public Price(Double value, Currency currency) { + this.value = value; + this.currency = currency; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Price price = (Price) o; + return Objects.equals(value, price.value) && currency == price.currency; + } + + @Override + public int hashCode() { + return Objects.hash(value, currency); + } +} + diff --git a/src/main/java/dev/biswajit/ecomm/productservice/model/Product.java b/src/main/java/dev/biswajit/ecomm/productservice/model/Product.java new file mode 100644 index 0000000..c8b3125 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/model/Product.java @@ -0,0 +1,42 @@ +package dev.biswajit.ecomm.productservice.model; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.BatchSize; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "PRODUCTS") +public class Product { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + @ManyToOne(cascade = {CascadeType.PERSIST}, fetch = FetchType.LAZY) + @JoinColumn(name = "category_id", referencedColumnName = "id") + private Category category; + + @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}, + fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "price_id", referencedColumnName = "id") + @BatchSize(size = 10) + @Fetch(FetchMode.SELECT) + private Price price; + + private String image; + + public Product(String title, Category category, Price price, String imageUrl) { + this.name = title; + this.category = category; + this.price = price; + this.image = imageUrl; + } +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/repository/CategoryRepository.java b/src/main/java/dev/biswajit/ecomm/productservice/repository/CategoryRepository.java new file mode 100644 index 0000000..fc520ad --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/repository/CategoryRepository.java @@ -0,0 +1,14 @@ +package dev.biswajit.ecomm.productservice.repository; + +import dev.biswajit.ecomm.productservice.model.Category; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.Optional; + +public interface CategoryRepository extends JpaRepository { + @Query("select c from Category c where lower(c.title) like lower(concat('%', :title, '%') ) ") + Optional findByTitle(@Param("title") String title); + +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/repository/PriceRepository.java b/src/main/java/dev/biswajit/ecomm/productservice/repository/PriceRepository.java new file mode 100644 index 0000000..ecd1bc8 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/repository/PriceRepository.java @@ -0,0 +1,13 @@ +package dev.biswajit.ecomm.productservice.repository; + +import dev.biswajit.ecomm.productservice.model.Price; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.Optional; +import java.util.UUID; + +public interface PriceRepository extends JpaRepository { + @Query("SELECT p FROM Price p where abs(p.value-0.01) <= :price and abs(p.value+0.01) >= :price") + Optional findByPriceValue(double price); +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/repository/ProductRepository.java b/src/main/java/dev/biswajit/ecomm/productservice/repository/ProductRepository.java new file mode 100644 index 0000000..271cd5f --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/repository/ProductRepository.java @@ -0,0 +1,23 @@ +package dev.biswajit.ecomm.productservice.repository; + +import dev.biswajit.ecomm.productservice.model.Product; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Primary +@Repository(value = "PRODUCT_REPOSITORY") +public interface ProductRepository extends JpaRepository { + +// Mono findProductById(Long id); + + @Query("select p from Product p join fetch p.category c join fetch p.price pr where c.title=:title") + List findProductsByCategory(@Param("title") String title); + + @Query("select p from Product p join fetch p.category c join fetch p.price pr") + List findAllProducts(); +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/service/CategoryService.java b/src/main/java/dev/biswajit/ecomm/productservice/service/CategoryService.java new file mode 100644 index 0000000..7baf454 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/service/CategoryService.java @@ -0,0 +1,13 @@ +package dev.biswajit.ecomm.productservice.service; + +import dev.biswajit.ecomm.productservice.dto.ProductDto; +import dev.biswajit.ecomm.productservice.model.Category; +import reactor.core.publisher.Mono; + +import java.util.List; + +public interface CategoryService { + Mono> allCategories(); + + Mono> findProductsByCategory(String category); +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/service/CategoryServiceImpl.java b/src/main/java/dev/biswajit/ecomm/productservice/service/CategoryServiceImpl.java new file mode 100644 index 0000000..f21bddb --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/service/CategoryServiceImpl.java @@ -0,0 +1,50 @@ +package dev.biswajit.ecomm.productservice.service; + +import dev.biswajit.ecomm.productservice.dto.ProductDto; +import dev.biswajit.ecomm.productservice.model.Category; +import dev.biswajit.ecomm.productservice.model.Product; +import dev.biswajit.ecomm.productservice.repository.CategoryRepository; +import dev.biswajit.ecomm.productservice.repository.ProductRepository; +import jakarta.transaction.Transactional; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.Objects; + +@Service +public class CategoryServiceImpl implements CategoryService{ + + private final CategoryRepository categoryRepository; + private final ProductRepository productRepository; + + public CategoryServiceImpl(CategoryRepository categoryRepository, + ProductRepository productRepository) { + this.categoryRepository = categoryRepository; + this.productRepository = productRepository; + } + + @Override + public Mono> allCategories() { + return Mono.just(categoryRepository.findAll() + .stream() + .filter(category -> Objects.nonNull(category.getTitle())).toList()); + } + + @Override + public Mono> findProductsByCategory(String title) { + List productsByCategory = productRepository.findProductsByCategory(title); + + List productDtoList = productsByCategory + .stream() + .map(product -> ProductDto.builder() + .id(product.getId()) + .title(product.getName()) + .category(product.getCategory().getTitle()) + .price(product.getPrice().getValue().toString()) + .imageUrl(product.getImage()) + .build()) + .toList(); + return Mono.just(productDtoList); + } +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/service/FakeStoreProductService.java b/src/main/java/dev/biswajit/ecomm/productservice/service/FakeStoreProductService.java new file mode 100644 index 0000000..2beb5b7 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/service/FakeStoreProductService.java @@ -0,0 +1,75 @@ +package dev.biswajit.ecomm.productservice.service; + +import dev.biswajit.ecomm.productservice.thirdparty.FakeStoreClient; +import dev.biswajit.ecomm.productservice.thirdparty.ThirdPartyProductDto; +import dev.biswajit.ecomm.productservice.dto.ProductDto; +import dev.biswajit.ecomm.productservice.exception.ProductNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.List; + +@Service("FAKE_STORE_SERVICE") +@ConditionalOnProperty(name = "app.service.type", havingValue = "FAKE_STORE_SERVICE") +public class FakeStoreProductService implements ProductService { + + private FakeStoreClient fakeStoreClient; + + public FakeStoreProductService(FakeStoreClient fakeStoreClient) { + this.fakeStoreClient = fakeStoreClient; + } + + @Override + public Mono productBy(Long id) { + return fakeStoreClient.getProductBy(id) + .switchIfEmpty(Mono.error(ProductNotFoundException.with("no product with id " + id + " found"))) + .map(product -> + new ProductDto(product.getId(), product.getTitle(), product.getPrice(), product.getCategory(), + product.getDescription(), product.getImageUrl())) + .log(); + } + + @Override + public Mono> allProducts() { + return fakeStoreClient.getAllProducts() + .flatMap(list -> { + List products = list.stream().map(it -> new ProductDto(it.getId(), it.getTitle(), it.getPrice(), it.getCategory(), + it.getDescription(), it.getImageUrl() + )).toList(); + return Mono.just(products); + }); + } + + @Override + public Mono add(ProductDto newProduct) { + + return fakeStoreClient.add(newProduct) + .map(it -> + new ProductDto(it.getId(), it.getTitle(), it.getPrice(), it.getCategory(), it.getDescription(), + it.getImageUrl())).log(); + } + + @Override + public Mono deleteBy(Long id) { + + return fakeStoreClient.deleteBy(id) + .map(it -> + new ProductDto(it.getId(), it.getTitle(), it.getPrice(), it.getCategory(), it.getDescription(), + it.getImageUrl())).log(); + } + + @Override + public Mono updateBy(Long id, ProductDto updateProductDto) { + + return fakeStoreClient.updateBy(id, updateProductDto) + .map(it -> + new ProductDto(it.getId(), it.getTitle(), it.getPrice(), it.getCategory(), + it.getDescription(), it.getImageUrl())).log(); + } +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/service/ProductService.java b/src/main/java/dev/biswajit/ecomm/productservice/service/ProductService.java new file mode 100644 index 0000000..aa94bce --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/service/ProductService.java @@ -0,0 +1,21 @@ +package dev.biswajit.ecomm.productservice.service; + +import dev.biswajit.ecomm.productservice.dto.ProductDto; +import dev.biswajit.ecomm.productservice.exception.ProductNotFoundException; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.UUID; + +public interface ProductService { + Mono productBy(Long id) throws ProductNotFoundException; + + Mono> allProducts(); + + Mono add(ProductDto newProduct); + + Mono deleteBy(Long id) throws ProductNotFoundException; + + Mono updateBy(Long id, ProductDto updateProductDto) throws ProductNotFoundException; + +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/service/SelfManagedProductService.java b/src/main/java/dev/biswajit/ecomm/productservice/service/SelfManagedProductService.java new file mode 100644 index 0000000..7ce0942 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/service/SelfManagedProductService.java @@ -0,0 +1,115 @@ +package dev.biswajit.ecomm.productservice.service; + +import dev.biswajit.ecomm.productservice.dto.ProductDto; +import dev.biswajit.ecomm.productservice.exception.ProductNotFoundException; +import dev.biswajit.ecomm.productservice.model.Category; +import dev.biswajit.ecomm.productservice.model.Currency; +import dev.biswajit.ecomm.productservice.model.Price; +import dev.biswajit.ecomm.productservice.model.Product; +import dev.biswajit.ecomm.productservice.repository.CategoryRepository; +import dev.biswajit.ecomm.productservice.repository.PriceRepository; +import dev.biswajit.ecomm.productservice.repository.ProductRepository; +import jakarta.transaction.Transactional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.Optional; + +@Primary +@Service("SELF_STORE_SERVICE") +@ConditionalOnProperty(name = "app.service.type", havingValue = "SELF_STORE_SERVICE") +public class SelfManagedProductService implements ProductService{ + private final ProductRepository productRepository; + private final CategoryRepository categoryRepository; + private final PriceRepository priceRepository; + + @Autowired + public SelfManagedProductService(@Autowired ProductRepository productRepository, + CategoryRepository categoryRepository, PriceRepository priceRepository) { + this.productRepository = productRepository; + this.categoryRepository = categoryRepository; + this.priceRepository = priceRepository; + } + + @Override + @Transactional + public Mono productBy(Long id) throws ProductNotFoundException { + +// has N+1 query issue since each call to a product will fetch category and price details + Product productFound = productRepository.findById(id) + .orElseThrow(() -> ProductNotFoundException.with(String.format("Product with %d not found", id))); + ProductDto productDto = new ProductDto(productFound.getId(), productFound.getName(), productFound.getPrice().getValue().toString(), + productFound.getCategory().getTitle(), productFound.getName(), productFound.getImage()); + + return Mono.just(productDto); + + } + + @Override + public Mono> allProducts() { + + return Mono.just(productRepository.findAllProducts() + .stream() + .map(productFound -> new ProductDto(productFound.getId(), productFound.getName(), productFound.getPrice().getValue().toString(), + productFound.getCategory().getTitle(), productFound.getName(), productFound.getImage())) + .toList()); + } + + @Override + @Transactional + public Mono add(ProductDto newProduct) { + Category categoryToBeSaved = categoryRepository.findByTitle(newProduct.getCategory()) + .orElse(new Category(newProduct.getCategory())); + Price price = new Price(Double.parseDouble(newProduct.getPrice()), Currency.RUPEE); + + Product product = new Product(newProduct.getTitle(), + categoryToBeSaved, price, newProduct.getImageUrl()); + + Product savedProduct = productRepository.save(product); + + return Mono.just( + new ProductDto(savedProduct.getId(), savedProduct.getName(), savedProduct.getPrice().getValue().toString(), + savedProduct.getCategory().getTitle(), savedProduct.getName(), savedProduct.getImage()) + ); + } + + @Override + @Transactional + public Mono deleteBy(Long id) throws ProductNotFoundException { + + Mono productDto = productBy(id); + + productRepository.deleteById(id); + + return productDto; + } + + @Override + @Transactional + public Mono updateBy(Long id, ProductDto updateProductDto) throws ProductNotFoundException { + Mono productDto = productBy(id); + + Category category = categoryRepository.findByTitle(updateProductDto.getTitle()) + .orElse(new Category(updateProductDto.getCategory())); + + Price price = priceRepository.findByPriceValue(Double.parseDouble(updateProductDto.getPrice())) + .orElse(new Price(Double.parseDouble(updateProductDto.getPrice()), Currency.RUPEE)); + + Mono updatedProduct = productDto.map(productToBeSaved -> + new Product(productToBeSaved.getId(), + updateProductDto.getTitle(), + category, + price, + updateProductDto.getImageUrl())) + .map(productRepository::save); + + return updatedProduct.map(product -> + new ProductDto(product.getId(), product.getName(), product.getPrice().getValue().toString(), + product.getCategory().getTitle(), product.getName(), product.getImage())); + } + +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/thirdparty/FakeStoreClient.java b/src/main/java/dev/biswajit/ecomm/productservice/thirdparty/FakeStoreClient.java new file mode 100644 index 0000000..99077f3 --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/thirdparty/FakeStoreClient.java @@ -0,0 +1,70 @@ +package dev.biswajit.ecomm.productservice.thirdparty; + +import dev.biswajit.ecomm.productservice.dto.ProductDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.List; + +@Component +public class FakeStoreClient { + private final WebClient webclient; + + public FakeStoreClient(@Autowired WebClient.Builder builder, @Value("${app.fakestore.url}") String baseUrl) { + this.webclient = builder.baseUrl(baseUrl).build(); + } + + public Mono getProductBy(Long id) { + return webclient + .get() + .uri("/products/{id}", id) + .retrieve() + .bodyToMono(ThirdPartyProductDto.class) + .log(); + } + + public Mono> getAllProducts() { + return webclient + .get() + .uri("/products") + .retrieve() + .bodyToMono(new ParameterizedTypeReference>() { + }) + .log(); + } + + public Mono add(ProductDto newProduct) { + return webclient + .post() + .uri("/products") + .body(BodyInserters.fromValue(newProduct)) + .retrieve() + .bodyToMono(ThirdPartyProductDto.class) + .log(); + } + + // todo - refactor to pass third party product dto instead of ProductDto + public Mono updateBy(Long id, ProductDto updateProductDto) { + return webclient + .put() + .uri("/products/{id}", id) + .body(BodyInserters.fromValue(updateProductDto)) + .retrieve() + .bodyToMono(ThirdPartyProductDto.class) + .log(); + } + + public Mono deleteBy(Long id) { + return webclient + .delete() + .uri("/products/{id}", id) + .retrieve() + .bodyToMono(ThirdPartyProductDto.class) + .log(); + } +} diff --git a/src/main/java/dev/biswajit/ecomm/productservice/thirdparty/ThirdPartyProductDto.java b/src/main/java/dev/biswajit/ecomm/productservice/thirdparty/ThirdPartyProductDto.java new file mode 100644 index 0000000..2310c7a --- /dev/null +++ b/src/main/java/dev/biswajit/ecomm/productservice/thirdparty/ThirdPartyProductDto.java @@ -0,0 +1,18 @@ +package dev.biswajit.ecomm.productservice.thirdparty; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.*; + +@NoArgsConstructor +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +@Data +public class ThirdPartyProductDto { + private Long id; + private String title; + private String price; + private String category; + private String description; + private String imageUrl; +} diff --git a/src/main/java/dev/naman/productservice/ProductserviceApplication.java b/src/main/java/dev/naman/productservice/ProductserviceApplication.java deleted file mode 100644 index 1620741..0000000 --- a/src/main/java/dev/naman/productservice/ProductserviceApplication.java +++ /dev/null @@ -1,119 +0,0 @@ -package dev.naman.productservice; - -import dev.naman.productservice.inheritancedemo.joinedtable.Mentor; -import dev.naman.productservice.inheritancedemo.joinedtable.MentorRepository; -import dev.naman.productservice.inheritancedemo.joinedtable.User; -import dev.naman.productservice.inheritancedemo.joinedtable.UserRepository; -import dev.naman.productservice.models.Category; -import dev.naman.productservice.models.Price; -import dev.naman.productservice.models.Product; -import dev.naman.productservice.repositories.CategoryRepository; -import dev.naman.productservice.repositories.PriceRepository; -import dev.naman.productservice.repositories.ProductRepository; -import jakarta.transaction.Transactional; -import org.hibernate.Hibernate; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@SpringBootApplication -public class ProductserviceApplication {// implements CommandLineRunner { - -// private MentorRepository mentorRepository; -// -// -// private UserRepository userRepository; -// private final ProductRepository productRepository; -// private final CategoryRepository categoryRepository; -// private final PriceRepository priceRepository; -// -// public ProductserviceApplication(@Qualifier("jt_mr") MentorRepository mentorRepository, -// @Qualifier("jt_ur") UserRepository userRepository, -// ProductRepository productRepository, -// CategoryRepository categoryRepository, -// PriceRepository priceRepository) { -// this.mentorRepository = mentorRepository; -// this.userRepository = userRepository; -// this.productRepository = productRepository; -// this.categoryRepository = categoryRepository; -// this.priceRepository = priceRepository; -// } - - public static void main(String[] args) { - SpringApplication.run(ProductserviceApplication.class, args); - } - -// @Transactional() -// @Override -// public void run(String... args) throws Exception { -//// Mentor mentor = new Mentor(); -//// mentor.setName("Naman"); -//// mentor.setEmail("Naman@scaler.com"); -//// mentor.setAverageRating(4.65); -//// mentorRepository.save(mentor); -//// -//// User user = new User(); -//// user.setName("Sarath"); -//// user.setEmail("sarathcool@yopmail.com"); -//// userRepository.save(user); -//// -//// List users = userRepository.findAll(); -//// for (User user1: users) { -//// System.out.println(user1); -//// } -// -// Category category = new Category(); -// category.setName("Apple Devices"); -//// Category savedCategory = categoryRepository.save(category); -// -// Price price = new Price("Rupee", 10); -//// Price savedPrice = priceRepository.save(price); -// -// Product product = new Product(); -// product.setTitle("iPhone 15 Pro"); -// product.setDescription("The best iPhone Ever"); -// product.setCategory(category); -// product.setPrice(price); -// -// productRepository.save(product); -// -// productRepository.deleteById(UUID.fromString("95672ed6-3127-4248-ae33-97a261c0a6f4")); -// -// System.out.println(productRepository.countAllByPrice_Currency("Rupee")); -// List products = productRepository.findAllByPrice_Currency("Rupee"); -//// Category category1 = categoryRepository.findById(UUID.fromString("5e6f679e-f326-44ae-b220-544b3822ab00")).get(); -//// System.out.println("Category name is: " + category1.getName()); -//// System.out.println("Printing all products in the category"); -////// Thread.sleep(1000); -//// -//// System.out.println(category1.getProducts().size()); -//// category1.getProducts().forEach( -//// product1 -> System.out.println(product1.getTitle()) -//// ); -//// -//// for (Product product1: category1.getProducts()) { -//// try { -//// System.out.println(product1.getTitle()); -//// } catch (Exception e) { -//// System.out.println(e.getMessage()); -//// } -//// } -// -// List products1 = productRepository.findAllByTitle("iPhone 15 Pro"); -// -// System.out.println("Fetching category b8f1f459-f9e9-4d3d-b115-f1f5267bd54f"); -// Thread.sleep(1000); -// Category category1 = categoryRepository.findById(UUID.fromString("b8f1f459-f9e9-4d3d-b115-f1f5267bd54f")).get(); -//// Category category1 = category1Optional.get(); -// -// System.out.println("Fetching products for category"); -// Thread.sleep(1000); -// List products11 = category1.getProducts(); -// } - -} diff --git a/src/main/java/dev/naman/productservice/controllers/CategoryController.java b/src/main/java/dev/naman/productservice/controllers/CategoryController.java deleted file mode 100644 index be875bb..0000000 --- a/src/main/java/dev/naman/productservice/controllers/CategoryController.java +++ /dev/null @@ -1,49 +0,0 @@ -package dev.naman.productservice.controllers; - -import dev.naman.productservice.dtos.GetProductTitlesRequestDto; -import dev.naman.productservice.dtos.ProductDto; -import dev.naman.productservice.models.Category; -import dev.naman.productservice.models.Product; -import dev.naman.productservice.services.CategoryService; -import org.springframework.web.bind.annotation.*; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -@RestController -@RequestMapping("/categories") -public class CategoryController { - private CategoryService categoryService; - - public CategoryController(CategoryService categoryService) { - this.categoryService = categoryService; - } - - @GetMapping("/{uuid}") - public List getCategory(@PathVariable("uuid") String uuid) { - List products = categoryService.getCategory(uuid).getProducts(); - - List productDtos = new ArrayList<>(); - - for (Product product: products) { - ProductDto productDto = new ProductDto(); - productDto.setDescription(product.getDescription()); - productDto.setTitle(product.getTitle()); - productDto.setImage(product.getImage()); - productDto.setPrice(product.getPrice()); - productDtos.add(productDto); -// productDto.se - } - - return productDtos; - } - - @GetMapping("/titles/") - public List getProductTitles(@RequestBody GetProductTitlesRequestDto requestDto) { - - List uuids = requestDto.getUuids(); - - return categoryService.getProductTitles(uuids); - } -} diff --git a/src/main/java/dev/naman/productservice/controllers/ProductController.java b/src/main/java/dev/naman/productservice/controllers/ProductController.java deleted file mode 100644 index 2602c25..0000000 --- a/src/main/java/dev/naman/productservice/controllers/ProductController.java +++ /dev/null @@ -1,73 +0,0 @@ -package dev.naman.productservice.controllers; - -import dev.naman.productservice.dtos.ExceptionDto; -import dev.naman.productservice.dtos.GenericProductDto; -import dev.naman.productservice.exceptions.NotFoundException; -import dev.naman.productservice.services.ProductService; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@RestController -@RequestMapping("/products") -public class ProductController { -// @Autowired - // field injection - private ProductService productService; - // ....; - // ...; - - - - // constructor injection -// @Autowired - public ProductController(ProductService productService) { - this.productService = productService; - } -// - - // setter injection -// @Autowired -// public void setProductService(ProductService productService) { -// this.productService = productService; -// } - - // GET /products {} - @GetMapping - public List getAllProducts() { - return productService.getAllProducts(); - } - - // localhost:8080/products/{id} - // localhost:8080/products/123 - @GetMapping("{id}") - public GenericProductDto getProductById(@PathVariable("id") Long id) throws NotFoundException { - GenericProductDto productDto = productService.getProductById(id); - if (productDto == null) { - // throw NotFoundException - } - return productDto; - } - - @DeleteMapping("{id}") - public ResponseEntity deleteProductById(@PathVariable("id") Long id) { - return new ResponseEntity<>( - productService.deleteProduct(id), - HttpStatus.OK - ); - } - - @PostMapping - public GenericProductDto createProduct(@RequestBody GenericProductDto product) { -// System.out.println(product.name); - return productService.createProduct(product); - } - - @PutMapping("{id}") - public void updateProductById() { - - } -} diff --git a/src/main/java/dev/naman/productservice/dtos/CategoryDto.java b/src/main/java/dev/naman/productservice/dtos/CategoryDto.java deleted file mode 100644 index fabb541..0000000 --- a/src/main/java/dev/naman/productservice/dtos/CategoryDto.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.naman.productservice.dtos; - -import lombok.Getter; -import lombok.Setter; - -import java.util.List; - -@Getter -@Setter -public class CategoryDto { - private String name; - - private List products; -} diff --git a/src/main/java/dev/naman/productservice/dtos/ExceptionDto.java b/src/main/java/dev/naman/productservice/dtos/ExceptionDto.java deleted file mode 100644 index 8fe5a05..0000000 --- a/src/main/java/dev/naman/productservice/dtos/ExceptionDto.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.naman.productservice.dtos; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.http.HttpStatus; - -@Getter -@Setter -public class ExceptionDto { - private HttpStatus errorCode; - private String message; - - public ExceptionDto(HttpStatus status, String message) { - this.errorCode = status; - this.message = message; - } -} diff --git a/src/main/java/dev/naman/productservice/dtos/GenericProductDto.java b/src/main/java/dev/naman/productservice/dtos/GenericProductDto.java deleted file mode 100644 index ea81d6c..0000000 --- a/src/main/java/dev/naman/productservice/dtos/GenericProductDto.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.naman.productservice.dtos; - -import dev.naman.productservice.models.Category; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class GenericProductDto { - private Long id; - private String title; - private String description; - private String image; - private String category; - private double price; -} diff --git a/src/main/java/dev/naman/productservice/dtos/GetProductTitlesRequestDto.java b/src/main/java/dev/naman/productservice/dtos/GetProductTitlesRequestDto.java deleted file mode 100644 index bb61e86..0000000 --- a/src/main/java/dev/naman/productservice/dtos/GetProductTitlesRequestDto.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.naman.productservice.dtos; - -import lombok.Getter; -import lombok.Setter; - -import java.util.List; - -@Getter -@Setter -public class GetProductTitlesRequestDto { - private List uuids; -} diff --git a/src/main/java/dev/naman/productservice/dtos/ProductDto.java b/src/main/java/dev/naman/productservice/dtos/ProductDto.java deleted file mode 100644 index 9f2d39f..0000000 --- a/src/main/java/dev/naman/productservice/dtos/ProductDto.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.naman.productservice.dtos; - -import dev.naman.productservice.models.Category; -import dev.naman.productservice.models.Price; -import jakarta.persistence.CascadeType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class ProductDto { - private String title; - - private String description; - - private String image; - // P : C - // => L to R: 1 : 1 - // => R to L: m : 1 - // => Ans: m : 1 - private Price price; -} diff --git a/src/main/java/dev/naman/productservice/exceptions/ControllerAdvices.java b/src/main/java/dev/naman/productservice/exceptions/ControllerAdvices.java deleted file mode 100644 index a1c2361..0000000 --- a/src/main/java/dev/naman/productservice/exceptions/ControllerAdvices.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.naman.productservice.exceptions; - -import dev.naman.productservice.dtos.ExceptionDto; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; - -@ControllerAdvice -public class ControllerAdvices { -// @ExceptionHandler(NotFoundException.class) -// private ResponseEntity handleNotFoundException( -// NotFoundException notFoundException -// ) { -// -// return new ResponseEntity( -// new ExceptionDto(HttpStatus.NOT_FOUND, notFoundException.getMessage()), -// HttpStatus.NOT_FOUND -// ); -// } -// -// @ExceptionHandler(ArrayIndexOutOfBoundsException.class) -// private ResponseEntity handleArrayIndexOutOfBound( -// ArrayIndexOutOfBoundsException notFoundException -// ) { -// -// return new ResponseEntity( -// new ExceptionDto(HttpStatus.NOT_FOUND, notFoundException.getMessage()), -// HttpStatus.NOT_FOUND -// ); -// } -} diff --git a/src/main/java/dev/naman/productservice/exceptions/NotFoundException.java b/src/main/java/dev/naman/productservice/exceptions/NotFoundException.java deleted file mode 100644 index 0986b0e..0000000 --- a/src/main/java/dev/naman/productservice/exceptions/NotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.naman.productservice.exceptions; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(value = HttpStatus.NOT_FOUND) -public class NotFoundException extends Exception { - - public NotFoundException(String message) { - super(message); - } -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/Mentor.java b/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/Mentor.java deleted file mode 100644 index 2e06842..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/Mentor.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.naman.productservice.inheritancedemo.joinedtable; - -import jakarta.persistence.Entity; -import jakarta.persistence.PrimaryKeyJoinColumn; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "jt_mentor") -@PrimaryKeyJoinColumn(name = "user_id") -public class Mentor extends User { - private double averageRating; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/MentorRepository.java b/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/MentorRepository.java deleted file mode 100644 index 567c201..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/MentorRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.naman.productservice.inheritancedemo.joinedtable; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository("jt_mr") -public interface MentorRepository -extends JpaRepository { - @Override - S save(S entity); -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/Student.java b/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/Student.java deleted file mode 100644 index d327d8f..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/Student.java +++ /dev/null @@ -1,15 +0,0 @@ -package dev.naman.productservice.inheritancedemo.joinedtable; - -import jakarta.persistence.Entity; -import jakarta.persistence.PrimaryKeyJoinColumn; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "jt_student") -@PrimaryKeyJoinColumn(name = "user_id") -public class Student extends User { - private double psp; - private double attendance; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/TA.java b/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/TA.java deleted file mode 100644 index 7e34534..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/TA.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.naman.productservice.inheritancedemo.joinedtable; - -import jakarta.persistence.Entity; -import jakarta.persistence.PrimaryKeyJoinColumn; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "jt_ta") -@PrimaryKeyJoinColumn(name = "user_id") -public class TA extends User { - private double averageRating; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/User.java b/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/User.java deleted file mode 100644 index 5c1e921..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/User.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.naman.productservice.inheritancedemo.joinedtable; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@Entity(name = "jt_user") -@Inheritance(strategy = InheritanceType.JOINED) -public class User { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - private String name; - private String email; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/UserRepository.java b/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/UserRepository.java deleted file mode 100644 index 581462b..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/joinedtable/UserRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.naman.productservice.inheritancedemo.joinedtable; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository("jt_ur") -public interface UserRepository -extends JpaRepository { - - @Override - S save(S entity); -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/Mentor.java b/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/Mentor.java deleted file mode 100644 index 0a08459..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/Mentor.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.naman.productservice.inheritancedemo.mappedsuperclass; - -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "ms_mentor") -public class Mentor extends User { - private double averageRating; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/Student.java b/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/Student.java deleted file mode 100644 index a7b2989..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/Student.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.naman.productservice.inheritancedemo.mappedsuperclass; - -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "ms_student") -public class Student extends User { - private double psp; - private double attendance; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/TA.java b/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/TA.java deleted file mode 100644 index 735d058..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/TA.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.naman.productservice.inheritancedemo.mappedsuperclass; - -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "ms_ta") -public class TA extends User { - private double averageRating; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/User.java b/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/User.java deleted file mode 100644 index bd1bdfb..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/mappedsuperclass/User.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.naman.productservice.inheritancedemo.mappedsuperclass; - -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.MappedSuperclass; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@MappedSuperclass -public class User { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - private String name; - private String email; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/Mentor.java b/src/main/java/dev/naman/productservice/inheritancedemo/singletable/Mentor.java deleted file mode 100644 index 20424a3..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/Mentor.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.naman.productservice.inheritancedemo.singletable; - -import jakarta.persistence.DiscriminatorValue; -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "st_mentor") -@DiscriminatorValue(value = "3") -public class Mentor extends User { - private double averageRating; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/MentorRepository.java b/src/main/java/dev/naman/productservice/inheritancedemo/singletable/MentorRepository.java deleted file mode 100644 index 1402125..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/MentorRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.naman.productservice.inheritancedemo.singletable; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository("st_mr") -public interface MentorRepository -extends JpaRepository { - @Override - S save(S entity); -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/Student.java b/src/main/java/dev/naman/productservice/inheritancedemo/singletable/Student.java deleted file mode 100644 index f711c1b..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/Student.java +++ /dev/null @@ -1,15 +0,0 @@ -package dev.naman.productservice.inheritancedemo.singletable; - -import jakarta.persistence.DiscriminatorValue; -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "st_student") -@DiscriminatorValue(value = "1") -public class Student extends User { - private double psp; - private double attendance; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/TA.java b/src/main/java/dev/naman/productservice/inheritancedemo/singletable/TA.java deleted file mode 100644 index 6950eaa..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/TA.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.naman.productservice.inheritancedemo.singletable; - -import jakarta.persistence.DiscriminatorValue; -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "st_ta") -@DiscriminatorValue(value = "2") -public class TA extends User { - private double averageRating; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/User.java b/src/main/java/dev/naman/productservice/inheritancedemo/singletable/User.java deleted file mode 100644 index d596463..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/User.java +++ /dev/null @@ -1,22 +0,0 @@ -package dev.naman.productservice.inheritancedemo.singletable; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "st_user") -@Inheritance(strategy = InheritanceType.SINGLE_TABLE) -@DiscriminatorColumn( - name = "userType", - discriminatorType = DiscriminatorType.INTEGER -) -@DiscriminatorValue(value = "0") -public class User { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - private String name; - private String email; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/UserRepository.java b/src/main/java/dev/naman/productservice/inheritancedemo/singletable/UserRepository.java deleted file mode 100644 index cd4604e..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/singletable/UserRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.naman.productservice.inheritancedemo.singletable; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository("st_ur") -public interface UserRepository -extends JpaRepository { - - @Override - S save(S entity); -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/Mentor.java b/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/Mentor.java deleted file mode 100644 index df47423..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/Mentor.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.naman.productservice.inheritancedemo.tableperclass; - -import jakarta.persistence.DiscriminatorValue; -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "tpc_mentor") -public class Mentor extends User { - private double averageRating; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/MentorRepository.java b/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/MentorRepository.java deleted file mode 100644 index 9c7dbe3..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/MentorRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.naman.productservice.inheritancedemo.tableperclass; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository("tpc_mr") -public interface MentorRepository -extends JpaRepository { - @Override - S save(S entity); -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/Student.java b/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/Student.java deleted file mode 100644 index ce25676..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/Student.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.naman.productservice.inheritancedemo.tableperclass; - -import jakarta.persistence.DiscriminatorValue; -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "tpc_student") -public class Student extends User { - private double psp; - private double attendance; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/TA.java b/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/TA.java deleted file mode 100644 index da42ce9..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/TA.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.naman.productservice.inheritancedemo.tableperclass; - -import jakarta.persistence.DiscriminatorValue; -import jakarta.persistence.Entity; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity(name = "tpc_ta") -public class TA extends User { - private double averageRating; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/User.java b/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/User.java deleted file mode 100644 index 3d9b3d4..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/User.java +++ /dev/null @@ -1,21 +0,0 @@ -package dev.naman.productservice.inheritancedemo.tableperclass; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -import java.util.UUID; - -@Getter -@Setter -@ToString -@Entity(name = "tpc_user") -@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) -public class User { - @Id -// @GeneratedValue(strategy = GenerationType.TABLE, generator="course") - private UUID id; - private String name; - private String email; -} diff --git a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/UserRepository.java b/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/UserRepository.java deleted file mode 100644 index 397d9ca..0000000 --- a/src/main/java/dev/naman/productservice/inheritancedemo/tableperclass/UserRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.naman.productservice.inheritancedemo.tableperclass; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository("tpc_ur") -public interface UserRepository -extends JpaRepository { - - @Override - S save(S entity); -} diff --git a/src/main/java/dev/naman/productservice/models/BaseModel.java b/src/main/java/dev/naman/productservice/models/BaseModel.java deleted file mode 100644 index c8ada58..0000000 --- a/src/main/java/dev/naman/productservice/models/BaseModel.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.naman.productservice.models; - -import jakarta.persistence.*; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.id.factory.spi.GenerationTypeStrategy; - -import java.util.UUID; - -@MappedSuperclass -public class BaseModel { - @Id - @GeneratedValue(generator = "naman") - @GenericGenerator(name = "naman", strategy = "uuid2") - @Column(name = "id", columnDefinition = "binary(16)", nullable = false, updatable = false) - private UUID uuid; -} diff --git a/src/main/java/dev/naman/productservice/models/Category.java b/src/main/java/dev/naman/productservice/models/Category.java deleted file mode 100644 index 4fd8f7f..0000000 --- a/src/main/java/dev/naman/productservice/models/Category.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.naman.productservice.models; - -import jakarta.persistence.*; -import lombok.*; -import org.hibernate.annotations.Fetch; -import org.hibernate.annotations.FetchMode; - -import java.util.ArrayList; -import java.util.List; - -@Entity -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -public class Category extends BaseModel { - @Column - private String name; - - @OneToMany(mappedBy = "category") - @Fetch(FetchMode.SELECT) - private List products = new ArrayList<>(); - - // this is the same relation being mapped by category attribute in the other (Product) class -} -// class Group { -// m:m -// List members; -// m:m -// List admins; -// -// 1----> 1 -// m<---- 1 -// m : 1 -// User creator; -// } \ No newline at end of file diff --git a/src/main/java/dev/naman/productservice/models/Order.java b/src/main/java/dev/naman/productservice/models/Order.java deleted file mode 100644 index 9ec7d46..0000000 --- a/src/main/java/dev/naman/productservice/models/Order.java +++ /dev/null @@ -1,21 +0,0 @@ -package dev.naman.productservice.models; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; - -import java.util.List; - -@Entity(name = "orders") -@Getter -@Setter -public class Order extends BaseModel { - - @ManyToMany() - @JoinTable( - name = "product_orders", - joinColumns = @JoinColumn(name = "order_id"), - inverseJoinColumns = @JoinColumn(name = "product_id") - ) - private List product; -} diff --git a/src/main/java/dev/naman/productservice/models/Price.java b/src/main/java/dev/naman/productservice/models/Price.java deleted file mode 100644 index 2b0d1a3..0000000 --- a/src/main/java/dev/naman/productservice/models/Price.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.naman.productservice.models; - -import jakarta.persistence.Entity; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Entity -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -public class Price extends BaseModel { - String currency; - double price; -} diff --git a/src/main/java/dev/naman/productservice/models/Product.java b/src/main/java/dev/naman/productservice/models/Product.java deleted file mode 100644 index ad6621b..0000000 --- a/src/main/java/dev/naman/productservice/models/Product.java +++ /dev/null @@ -1,34 +0,0 @@ -package dev.naman.productservice.models; - -import jakarta.annotation.Nullable; -import jakarta.persistence.*; -import lombok.*; -import org.hibernate.annotations.Fetch; -import org.hibernate.annotations.FetchMode; - -@Entity -@Getter -@Setter -@NoArgsConstructor -@AllArgsConstructor -public class Product extends BaseModel { - - private String title; - - private String description; - - private String image; - // P : C - // => L to R: 1 : 1 - // => R to L: m : 1 - // => Ans: m : 1 - @ManyToOne(cascade = {CascadeType.PERSIST}) - @JoinColumn(name = "category") - private Category category; - - @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY) -// @Fetch(FetchMode.JOIN) - private Price price; - private int inventoryCount; -// private double price; -} diff --git a/src/main/java/dev/naman/productservice/repositories/CategoryRepository.java b/src/main/java/dev/naman/productservice/repositories/CategoryRepository.java deleted file mode 100644 index 6521d4a..0000000 --- a/src/main/java/dev/naman/productservice/repositories/CategoryRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.naman.productservice.repositories; - -import dev.naman.productservice.models.Category; -import org.springframework.context.annotation.Lazy; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@Lazy -public interface CategoryRepository -extends JpaRepository { - - Optional findById(UUID uuid); - - @Override - List findAllById(Iterable uuids); -} diff --git a/src/main/java/dev/naman/productservice/repositories/CustomQueries.java b/src/main/java/dev/naman/productservice/repositories/CustomQueries.java deleted file mode 100644 index 161151e..0000000 --- a/src/main/java/dev/naman/productservice/repositories/CustomQueries.java +++ /dev/null @@ -1,6 +0,0 @@ -package dev.naman.productservice.repositories; - -public interface CustomQueries { - String FIND_ALL_BY_TITLE = "select * from product join product_orders " + - "on product.id = product_orders.product_id where title = :naman"; -} diff --git a/src/main/java/dev/naman/productservice/repositories/PriceRepository.java b/src/main/java/dev/naman/productservice/repositories/PriceRepository.java deleted file mode 100644 index bd06799..0000000 --- a/src/main/java/dev/naman/productservice/repositories/PriceRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package dev.naman.productservice.repositories; - -import dev.naman.productservice.models.Price; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface PriceRepository -extends JpaRepository { -} diff --git a/src/main/java/dev/naman/productservice/repositories/ProductRepository.java b/src/main/java/dev/naman/productservice/repositories/ProductRepository.java deleted file mode 100644 index c2bd45c..0000000 --- a/src/main/java/dev/naman/productservice/repositories/ProductRepository.java +++ /dev/null @@ -1,47 +0,0 @@ -package dev.naman.productservice.repositories; - -import dev.naman.productservice.models.Category; -import dev.naman.productservice.models.Product; -import org.springframework.data.domain.Example; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.FluentQuery; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.UUID; -import java.util.function.Function; - -@Repository -public interface ProductRepository -extends JpaRepository { - - Product findByTitleEquals(String title); - - Product findByTitleEqualsAndPrice_PriceOrderByPrice_price(String title, double price); - - List findAllByPrice_Currency(String currency); - - @Override - void delete(Product entity); - - long countAllByPrice_Currency(String currency); - - - List findAllByTitleLike(String titleRegex); - - List readAllByTitleLike(String titleRegex); - - - List findAllByCategoryIn(List categories); - - // @Query("select Product from Product where Product .category.uuid in :uuids") -// List findAllByCategoryIn(List uuids); - - - @Query(value = CustomQueries.FIND_ALL_BY_TITLE, nativeQuery = true) - List findAllByTitle(String naman); - -// @Query("select Product from Product where Product.price.currency = :currency and Product.title = :naman") -// List doSomething(String naman, String currency); -} diff --git a/src/main/java/dev/naman/productservice/services/CategoryService.java b/src/main/java/dev/naman/productservice/services/CategoryService.java deleted file mode 100644 index 91d2912..0000000 --- a/src/main/java/dev/naman/productservice/services/CategoryService.java +++ /dev/null @@ -1,10 +0,0 @@ -package dev.naman.productservice.services; - -import dev.naman.productservice.models.Category; - -import java.util.List; - -public interface CategoryService { - Category getCategory(String uuid); - List getProductTitles(List categoryUUIDs); -} diff --git a/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java b/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java deleted file mode 100644 index b167a55..0000000 --- a/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package dev.naman.productservice.services; - -import dev.naman.productservice.models.Category; -import dev.naman.productservice.models.Product; -import dev.naman.productservice.repositories.CategoryRepository; -import dev.naman.productservice.repositories.ProductRepository; -import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.RequestBody; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@Service -public class CategoryServiceImpl implements CategoryService { - private CategoryRepository categoryRepository; - private final ProductRepository productRepository; - - public CategoryServiceImpl(CategoryRepository categoryRepository, - ProductRepository productRepository) { - this.categoryRepository = categoryRepository; - this.productRepository = productRepository; - } - - @Override - public Category getCategory(String uuid) { - Optional categoryOptional = categoryRepository.findById(UUID.fromString(uuid)); - - if (categoryOptional.isEmpty()) { - return null; - } - - Category category = categoryOptional.get(); - - List products = category.getProducts(); - - - return category; - } - - public List getProductTitles(List categoryUUIDs) { - List uuids = new ArrayList<>(); - - for (String uuid: categoryUUIDs) { - uuids.add(UUID.fromString(uuid)); - } -// -// List categories = categoryRepository.findAllById(uuids); -// -// -// List titles = new ArrayList<>(); -// -// categories.forEach( -// category -> { -// category.getProducts().forEach( -// product -> { -// titles.add(product.getTitle()); -// } -// ); -// } -// ); -// -// -// return titles; - - List categories = categoryRepository.findAllById(uuids); - - List products = productRepository.findAllByCategoryIn(categories); - - List titles = new ArrayList<>(); - - for (Product p: products) { - titles.add(p.getTitle()); - } - - return titles; - } -} diff --git a/src/main/java/dev/naman/productservice/services/FakeStoreProductService.java b/src/main/java/dev/naman/productservice/services/FakeStoreProductService.java deleted file mode 100644 index ceb58af..0000000 --- a/src/main/java/dev/naman/productservice/services/FakeStoreProductService.java +++ /dev/null @@ -1,63 +0,0 @@ -package dev.naman.productservice.services; - -import dev.naman.productservice.dtos.GenericProductDto; -import dev.naman.productservice.exceptions.NotFoundException; -import dev.naman.productservice.thirdpartyclients.productsservice.fakestore.FakeStoreProductDto; -import dev.naman.productservice.thirdpartyclients.productsservice.fakestore.FakeStoryProductServiceClient; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; -import org.springframework.stereotype.Repository; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.List; - - -@Repository("fakeStoreProductService") -public class FakeStoreProductService implements ProductService { - - private FakeStoryProductServiceClient fakeStoryProductServiceClient; - - private GenericProductDto convertFakeStoreProductIntoGenericProduct(FakeStoreProductDto fakeStoreProductDto) { - - GenericProductDto product = new GenericProductDto(); - product.setId(fakeStoreProductDto.getId()); - product.setImage(fakeStoreProductDto.getImage()); - product.setDescription(fakeStoreProductDto.getDescription()); - product.setTitle(fakeStoreProductDto.getTitle()); - product.setPrice(fakeStoreProductDto.getPrice()); - product.setCategory(fakeStoreProductDto.getCategory()); - - return product; - } - - public FakeStoreProductService(FakeStoryProductServiceClient fakeStoryProductServiceClient) { - this.fakeStoryProductServiceClient = fakeStoryProductServiceClient; - } - - - @Override - public GenericProductDto createProduct(GenericProductDto product) { - return convertFakeStoreProductIntoGenericProduct(fakeStoryProductServiceClient.createProduct(product)); - } - - @Override - public GenericProductDto getProductById(Long id) throws NotFoundException { - return convertFakeStoreProductIntoGenericProduct(fakeStoryProductServiceClient.getProductById(id)); - } - - @Override - public List getAllProducts() { - List genericProductDtos = new ArrayList<>(); - - for (FakeStoreProductDto fakeStoreProductDto: fakeStoryProductServiceClient.getAllProducts()) { - genericProductDtos.add(convertFakeStoreProductIntoGenericProduct(fakeStoreProductDto)); - } - return genericProductDtos; - } - - @Override - public GenericProductDto deleteProduct(Long id) { - return convertFakeStoreProductIntoGenericProduct(fakeStoryProductServiceClient.deleteProduct(id)); - } -} diff --git a/src/main/java/dev/naman/productservice/services/ProductService.java b/src/main/java/dev/naman/productservice/services/ProductService.java deleted file mode 100644 index bc5eb10..0000000 --- a/src/main/java/dev/naman/productservice/services/ProductService.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.naman.productservice.services; - -import dev.naman.productservice.dtos.GenericProductDto; -import dev.naman.productservice.exceptions.NotFoundException; - -import java.util.List; - -public interface ProductService { - - GenericProductDto createProduct(GenericProductDto product); - - GenericProductDto getProductById(Long id) throws NotFoundException; - - List getAllProducts(); - - GenericProductDto deleteProduct(Long id); -} diff --git a/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java b/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java deleted file mode 100644 index a50d666..0000000 --- a/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package dev.naman.productservice.services; - -import dev.naman.productservice.dtos.GenericProductDto; -import dev.naman.productservice.models.Product; -import dev.naman.productservice.repositories.ProductRepository; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; - -import java.util.List; - - -@Primary -@Service("selfProductServiceImpl") -public class SelfProductServiceImpl implements ProductService { - private ProductRepository productRepository; - - public SelfProductServiceImpl(ProductRepository productRepository) { - this.productRepository = productRepository; - } - - @Override - public GenericProductDto getProductById(Long id) { - - - return new GenericProductDto(); - } - - @Override - public GenericProductDto createProduct(GenericProductDto product) { - return null; - } - - @Override - public List getAllProducts() { - return null; - } - - @Override - public GenericProductDto deleteProduct(Long id) { - return null; - } -} diff --git a/src/main/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoreProductDto.java b/src/main/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoreProductDto.java deleted file mode 100644 index 67846c9..0000000 --- a/src/main/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoreProductDto.java +++ /dev/null @@ -1,18 +0,0 @@ -package dev.naman.productservice.thirdpartyclients.productsservice.fakestore; - -import dev.naman.productservice.models.Category; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -public class FakeStoreProductDto { - private Long id; - private String title; - private double price; - private String category; - private String description; - private String image; -} - -// Break till 10:35 \ No newline at end of file diff --git a/src/main/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoryProductServiceClient.java b/src/main/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoryProductServiceClient.java deleted file mode 100644 index 6af4a08..0000000 --- a/src/main/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoryProductServiceClient.java +++ /dev/null @@ -1,97 +0,0 @@ -package dev.naman.productservice.thirdpartyclients.productsservice.fakestore; - -import dev.naman.productservice.dtos.GenericProductDto; -import dev.naman.productservice.exceptions.NotFoundException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; -import org.springframework.web.client.RequestCallback; -import org.springframework.web.client.ResponseExtractor; -import org.springframework.web.client.RestTemplate; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/*** - * Wrapper over FakeStore API - */ -@Service -public class FakeStoryProductServiceClient { - private RestTemplateBuilder restTemplateBuilder; - - - @Value("${fakestore.api.url}") - private String fakeStoreApiUrl; - - @Value("${fakestore.api.paths.product}") - private String fakeStoreProductsApiPath; - - private String specificProductRequestUrl ; - private String productRequestsBaseUrl ; - - public FakeStoryProductServiceClient(RestTemplateBuilder restTemplateBuilder, - @Value("${fakestore.api.url}") String fakeStoreApiUrl, - @Value("${fakestore.api.paths.product}") String fakeStoreProductsApiPath) { - this.restTemplateBuilder = restTemplateBuilder; - this.productRequestsBaseUrl = fakeStoreApiUrl + fakeStoreProductsApiPath; - this.specificProductRequestUrl = fakeStoreApiUrl + fakeStoreProductsApiPath + "/{id}"; - } - - - public FakeStoreProductDto createProduct(GenericProductDto product) { - RestTemplate restTemplate = restTemplateBuilder.build(); - ResponseEntity response = restTemplate.postForEntity( - productRequestsBaseUrl, product, FakeStoreProductDto.class - ); - - return response.getBody(); - } - - public FakeStoreProductDto getProductById(Long id) throws NotFoundException { -// FakeStoreProductService fakeStoreProductService = new FakeStoreProductService(); - RestTemplate restTemplate = restTemplateBuilder.build(); - ResponseEntity response = - restTemplate.getForEntity(specificProductRequestUrl, FakeStoreProductDto.class, id); - - FakeStoreProductDto fakeStoreProductDto = response.getBody(); - - if (fakeStoreProductDto == null) { - throw new NotFoundException("Product with id: " + id + " doesn't exist."); -// return null; - } - -// null == null - -// response.getStatusCode() - - return fakeStoreProductDto; -// return null; - } - - public List getAllProducts() { - RestTemplate restTemplate = restTemplateBuilder.build(); - - ResponseEntity response = - restTemplate.getForEntity(productRequestsBaseUrl, FakeStoreProductDto[].class); - - List answer = new ArrayList<>(); - - return Arrays.stream(response.getBody()).toList(); - } - - public FakeStoreProductDto deleteProduct(Long id) { - RestTemplate restTemplate = restTemplateBuilder.build(); - - - RequestCallback requestCallback = restTemplate.acceptHeaderRequestCallback(FakeStoreProductDto.class); - ResponseExtractor> responseExtractor = - restTemplate.responseEntityExtractor(FakeStoreProductDto.class); - ResponseEntity response = restTemplate.execute(specificProductRequestUrl, HttpMethod.DELETE, - requestCallback, responseExtractor, id); - - return response.getBody(); - } -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index d032b9b..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,20 +0,0 @@ -productservice.type=fakeStoreProductService -ayush.goyal=fakeStoreProductService -naman.bhalla=abc -server.port=3000 -# hashmap key:value - - -# Fakestore Config Values -fakestore.api.url=https://fakestoreapi.com -fakestore.api.paths.product=/products - -server.error.include-stacktrace=never - -spring.jpa.hibernate.ddl-auto=validate -spring.datasource.url=jdbc:mysql://localhost:3306/sep23productservice -spring.datasource.username=sep23productservice -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.jpa.show-sql=true -#logging.level.org.hibernate.SQL=DEBUG -#logging.level.org.hibernate.type=TRACE diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..ef475c1 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,27 @@ +use: + custom: + repository: false + +app: + fakestore: + url: https://fakestoreapi.com + service: +# type: FAKE_STORE_SERVICE + type: SELF_STORE_SERVICE +spring: + jpa: + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + format_sql: true + dialect: org.hibernate.dialect.MySQL8Dialect + datasource: + url: jdbc:mysql://localhost:3306/scaler + username: root + password: secret + driver-class-name: com.mysql.cj.jdbc.Driver +logging: + level: + org.hibernate.sql: DEBUG diff --git a/src/main/resources/db/migration/V1__init_db.sql b/src/main/resources/db/migration/V1__init_db.sql deleted file mode 100644 index 4056c0f..0000000 --- a/src/main/resources/db/migration/V1__init_db.sql +++ /dev/null @@ -1,164 +0,0 @@ -CREATE TABLE category -( - id BINARY(16) NOT NULL, - name VARCHAR(255) NULL, - CONSTRAINT pk_category PRIMARY KEY (id) -); - -CREATE TABLE jt_mentor -( - user_id BIGINT NOT NULL, - average_rating DOUBLE NOT NULL, - CONSTRAINT pk_jt_mentor PRIMARY KEY (user_id) -); - -CREATE TABLE jt_student -( - user_id BIGINT NOT NULL, - psp DOUBLE NOT NULL, - attendance DOUBLE NOT NULL, - CONSTRAINT pk_jt_student PRIMARY KEY (user_id) -); - -CREATE TABLE jt_ta -( - user_id BIGINT NOT NULL, - average_rating DOUBLE NOT NULL, - CONSTRAINT pk_jt_ta PRIMARY KEY (user_id) -); - -CREATE TABLE jt_user -( - id BIGINT AUTO_INCREMENT NOT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - CONSTRAINT pk_jt_user PRIMARY KEY (id) -); - -CREATE TABLE ms_mentor -( - id BIGINT AUTO_INCREMENT NOT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - average_rating DOUBLE NOT NULL, - CONSTRAINT pk_ms_mentor PRIMARY KEY (id) -); - -CREATE TABLE ms_student -( - id BIGINT AUTO_INCREMENT NOT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - psp DOUBLE NOT NULL, - attendance DOUBLE NOT NULL, - CONSTRAINT pk_ms_student PRIMARY KEY (id) -); - -CREATE TABLE ms_ta -( - id BIGINT AUTO_INCREMENT NOT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - average_rating DOUBLE NOT NULL, - CONSTRAINT pk_ms_ta PRIMARY KEY (id) -); - -CREATE TABLE orders -( - id BINARY(16) NOT NULL, - CONSTRAINT pk_orders PRIMARY KEY (id) -); - -CREATE TABLE price -( - id BINARY(16) NOT NULL, - currency VARCHAR(255) NULL, - price DOUBLE NOT NULL, - CONSTRAINT pk_price PRIMARY KEY (id) -); - -CREATE TABLE product -( - id BINARY(16) NOT NULL, - title VARCHAR(255) NULL, - `description` VARCHAR(255) NULL, - image VARCHAR(255) NULL, - category BINARY(16) NULL, - price_id BINARY(16) NULL, - CONSTRAINT pk_product PRIMARY KEY (id) -); - -CREATE TABLE product_orders -( - order_id BINARY(16) NOT NULL, - product_id BINARY(16) NOT NULL -); - -CREATE TABLE st_user -( - id BIGINT AUTO_INCREMENT NOT NULL, - user_type INT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - average_rating DOUBLE NOT NULL, - psp DOUBLE NOT NULL, - attendance DOUBLE NOT NULL, - CONSTRAINT pk_st_user PRIMARY KEY (id) -); - -CREATE TABLE tpc_mentor -( - id BINARY(16) NOT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - average_rating DOUBLE NOT NULL, - CONSTRAINT pk_tpc_mentor PRIMARY KEY (id) -); - -CREATE TABLE tpc_student -( - id BINARY(16) NOT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - psp DOUBLE NOT NULL, - attendance DOUBLE NOT NULL, - CONSTRAINT pk_tpc_student PRIMARY KEY (id) -); - -CREATE TABLE tpc_ta -( - id BINARY(16) NOT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - average_rating DOUBLE NOT NULL, - CONSTRAINT pk_tpc_ta PRIMARY KEY (id) -); - -CREATE TABLE tpc_user -( - id BINARY(16) NOT NULL, - name VARCHAR(255) NULL, - email VARCHAR(255) NULL, - CONSTRAINT pk_tpc_user PRIMARY KEY (id) -); - -ALTER TABLE jt_mentor - ADD CONSTRAINT FK_JT_MENTOR_ON_USER FOREIGN KEY (user_id) REFERENCES jt_user (id); - -ALTER TABLE jt_student - ADD CONSTRAINT FK_JT_STUDENT_ON_USER FOREIGN KEY (user_id) REFERENCES jt_user (id); - -ALTER TABLE jt_ta - ADD CONSTRAINT FK_JT_TA_ON_USER FOREIGN KEY (user_id) REFERENCES jt_user (id); - -ALTER TABLE product - ADD CONSTRAINT FK_PRODUCT_ON_CATEGORY FOREIGN KEY (category) REFERENCES category (id); - -ALTER TABLE product - ADD CONSTRAINT FK_PRODUCT_ON_PRICE FOREIGN KEY (price_id) REFERENCES price (id); - -ALTER TABLE product_orders - ADD CONSTRAINT fk_proord_on_order FOREIGN KEY (order_id) REFERENCES orders (id); - -ALTER TABLE product_orders - ADD CONSTRAINT fk_proord_on_product FOREIGN KEY (product_id) REFERENCES product (id); \ No newline at end of file diff --git a/src/main/resources/db/migration/V2__add_something_add_column_inventory_count.sql b/src/main/resources/db/migration/V2__add_something_add_column_inventory_count.sql deleted file mode 100644 index 4f4fe1a..0000000 --- a/src/main/resources/db/migration/V2__add_something_add_column_inventory_count.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE something -( - id BINARY(16) NOT NULL, - CONSTRAINT pk_something PRIMARY KEY (id) -); - -ALTER TABLE product - ADD inventory_count INT NULL; - -ALTER TABLE product - MODIFY inventory_count INT NOT NULL; \ No newline at end of file diff --git a/src/test/java/dev/biswajit/ecomm/productservice/SelfManagedProductServiceApplicationTests.java b/src/test/java/dev/biswajit/ecomm/productservice/SelfManagedProductServiceApplicationTests.java new file mode 100644 index 0000000..a0b5a73 --- /dev/null +++ b/src/test/java/dev/biswajit/ecomm/productservice/SelfManagedProductServiceApplicationTests.java @@ -0,0 +1,13 @@ +package dev.biswajit.ecomm.productservice; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SelfManagedProductServiceApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/src/test/java/dev/biswajit/ecomm/productservice/productcontroller/ProductControllerIntegrationTest.java b/src/test/java/dev/biswajit/ecomm/productservice/productcontroller/ProductControllerIntegrationTest.java new file mode 100644 index 0000000..d8cb0b7 --- /dev/null +++ b/src/test/java/dev/biswajit/ecomm/productservice/productcontroller/ProductControllerIntegrationTest.java @@ -0,0 +1,44 @@ +package dev.biswajit.ecomm.productservice.productcontroller; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ActiveProfiles("test") +@SpringBootTest +@ExtendWith(SpringExtension.class) +public class ProductControllerIntegrationTest { + @Test + @Disabled + void shouldReturnProductWhenSearchedById() { + + } + + @Test + @Disabled + void shouldThrowExceptionWhenProductIsNotFound() { + + } + + @Test + @Disabled + void shouldReturnAllProducts() { + + } + + @Test + @Disabled + void shouldCreateProduct() { + + } + + @Test + @Disabled + void shouldUpdateTheProductAttributes() { + + } + +} diff --git a/src/test/java/dev/naman/productservice/ProductserviceApplicationTests.java b/src/test/java/dev/naman/productservice/ProductserviceApplicationTests.java deleted file mode 100644 index a149efa..0000000 --- a/src/test/java/dev/naman/productservice/ProductserviceApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.naman.productservice; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class ProductserviceApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/java/dev/naman/productservice/RandomTest.java b/src/test/java/dev/naman/productservice/RandomTest.java deleted file mode 100644 index eb71d20..0000000 --- a/src/test/java/dev/naman/productservice/RandomTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.naman.productservice; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Random; - -@SpringBootTest -public class RandomTest { -// @Test -// void testLessThan3() { -// Random random = new Random(); -// int number = random.nextInt(); -// -// assert(number < 10000000); -// } -} diff --git a/src/test/java/dev/naman/productservice/controllers/ProductControllerTest.java b/src/test/java/dev/naman/productservice/controllers/ProductControllerTest.java deleted file mode 100644 index 800e736..0000000 --- a/src/test/java/dev/naman/productservice/controllers/ProductControllerTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package dev.naman.productservice.controllers; - -import dev.naman.productservice.exceptions.NotFoundException; -import dev.naman.productservice.thirdpartyclients.productsservice.fakestore.FakeStoryProductServiceClient; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Random; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -public class ProductControllerTest { - - @Autowired - private FakeStoryProductServiceClient fakeStoryProductServiceClient; - - - @Test - @DisplayName("1 + 1 equals 2") - void onePlusOneEqualsTrue() throws NotFoundException { -// System.out.println("It is true"); -// assertEquals(11, 1 + 1, "one plus is not coming to be 11"); - -// assert - -// assertNull(fakeStoryProductServiceClient.getProductById(101L)); - -// Exception e; -// -// try { -// fakeStoryProductServiceClient.getProductById(101L); -// } catch (Exception ex) { -// e = ex; -// } -// -// assertNotNull(e); -// assertEquals(NotFoundException.class, e.getClass()); - -// assertEquals(null, fakeStoryProductServiceClient.getProductById(101L)); -// assertThrows(NotFoundException.class, () -> fakeStoryProductServiceClient.getProductById(101L)); -// -// assertEquals(true, 1 + 1 == 2); - assertTrue(returnSomething()); - } - - boolean returnSomething() { - Random random = new Random(); - return random.nextInt() % 2 == 0; - } - - @Test - void additionShouldBeCorrect() { - assertTrue(-1 + -1 == -2, "adding 2 negatives is not correct"); - - assertTrue(-1 + 0 == -1, "adding a negative and a zero is giving wrong answer"); - - assertTrue(-1 + 1 == 0); - - assert 1 + 0 == 1; - - assert 1 + 1 == 2; - } -} - -// Assertion Framework -// -> allows you to make assertions -// -> allows you to make checks \ No newline at end of file diff --git a/src/test/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoryProductServiceClientTest.java b/src/test/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoryProductServiceClientTest.java deleted file mode 100644 index d79b07f..0000000 --- a/src/test/java/dev/naman/productservice/thirdpartyclients/productsservice/fakestore/FakeStoryProductServiceClientTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package dev.naman.productservice.thirdpartyclients.productsservice.fakestore; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.RestTemplate; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -class FakeStoryProductServiceClientTest { - @Autowired - private RestTemplateBuilder restTemplateBuilder; - - @Test - void testNonExistingProductReturnsNull() { -// RestTemplate restTemplate = restTemplateBuilder.build(); -// ResponseEntity response = -// restTemplate.getForEntity(specificProductRequestUrl, FakeStoreProductDto.class, id); -// -// FakeStoreProductDto fakeStoreProductDto = response.getBody(); -// -// assertNull(fakeStoreProductDto); - } -} \ No newline at end of file