diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b876cf04d..000000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: java -sudo: required -services: - - docker -jdk: - - oraclejdk11 -install: true - -env: - - GROUP=weaveworksdemos COMMIT=$TRAVIS_COMMIT TAG=$TRAVIS_TAG REPO=carts; - -script: - - set -e - - travis_wait ./scripts/build.sh; - -after_success: - - set -e; - - if [ -z "$DOCKER_PASS" ] ; then - echo "This is a build triggered by an external PR. Skipping docker push."; - exit 0; - fi; - - docker login -u $DOCKER_USER -p $DOCKER_PASS; - - ./scripts/push.sh -notifications: - slack: - secure: jHh+ksay1dxGEMxxep6XllCR5VwsmuSyIpLgG9bUKpG4fPR948K5Ev2E/vyobrqbTi5JMWasXd3ecwzV1QIN8QvvQ33Fx70oSp9Cit5gvNmLWVplHkWiMnnLD33IMCbtDHK69FjH3GQyJ5HfgjiJSF2nTFaCArYImrCcnU+ENTXW9L3rlYm5ElnP/NfWbrqxIF4EOiCKHMM5kpFYWO8mYLTVilHhPLAz94IVV2OUTe4NUdBJgXolAJqg28QTcfrk5x0OudDTc3Ssa3f/ezrE0LgrzeWdekcrNdYt+YZYaQxiPOIhNyZu0RxU+46ip4XhUS6qSXxW1Kpf0RXkgdmTTbYxF31D4GG+SoTjbBONZqK+qw3AkuYxTQYZnl50n+Hd1gtKY31qCwFEAVUU/tYDI5oKUdUaDsiHU5J/Yt+YMPoyWZ7FOZYwSNy2xs78XGXqQnYn35lsBv0BmYo/1mPUFbrlZgVO5b5wki7NhuLKnqHo9GvkavG71py1VjJTShq5um4NrPBYZ/Y9aZtZD6E2BQPJBgciwGtoFdmaTzmPtwPkWMA+SlcAtpcQlFATXM7xS5324XYK9+okDoqybj1cmHIk1FLnM9nx3r+TUOGsUrlY2ZO9FIrljgII3H8vzcUCbwMwzaQvhsBCFBFZQ6umjbHxnRN9zRe52c4zkkCSAZc= diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8dada3eda..000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed 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 - - http://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. diff --git a/api-spec/hooks.js b/api-spec/hooks.js deleted file mode 100644 index 91e8bcab2..000000000 --- a/api-spec/hooks.js +++ /dev/null @@ -1,93 +0,0 @@ -const hooks = require('hooks'); -const {MongoClient} = require('mongodb'); -const ObjectID = require('mongodb').ObjectID; - -let db; - -const address = [ - {"_id":ObjectID("579f21ae98684924944651bd"),"_class":"works.weave.socks.users.entities.Address","number":"69","street":"Wilson Street","city":"Hartlepool","postcode":"TS26 8JU","country":"United Kingdom"}, - {"_id":ObjectID("579f21ae98684924944651c0"),"_class":"works.weave.socks.users.entities.Address","number":"122","street":"Radstone WayNet","city":"Northampton","postcode":"NN2 8NT","country":"United Kingdom"}, - {"_id":ObjectID("579f21ae98684924944651c3"),"_class":"works.weave.socks.users.entities.Address","number":"3","street":"Radstone Way","city":"Northampton","postcode":"NN2 8NT","country":"United Kingdom"} -]; - - -const card = [ - {"_id":ObjectID("579f21ae98684924944651be"),"_class":"works.weave.socks.users.entities.Card","longNum":"8575776807334952","expires":"08/19","ccv":"014"}, - {"_id":ObjectID("579f21ae98684924944651c1"),"_class":"works.weave.socks.users.entities.Card","longNum":"8918468841895184","expires":"08/19","ccv":"597"}, - {"_id":ObjectID("579f21ae98684924944651c4"),"_class":"works.weave.socks.users.entities.Card","longNum":"6426429851404909","expires":"08/19","ccv":"381"} -]; - -const cart = [ - {"_id":ObjectID("579f21de98689ebf2bf1cd2f"),"_class":"works.weave.socks.cart.entities.Cart","customerId":"579f21ae98684924944651bf","items":[{"$ref":"item","$id":ObjectID("579f227698689ebf2bf1cd31")},{"$ref":"item","$id":ObjectID("579f22ac98689ebf2bf1cd32")}]}, - {"_id":ObjectID("579f21e298689ebf2bf1cd30"),"_class":"works.weave.socks.cart.entities.Cart","customerId":"579f21ae98684924944651bfaa","items":[]} -]; - - -const item = [ - {"_id":ObjectID("579f227698689ebf2bf1cd31"),"_class":"works.weave.socks.cart.entities.Item","itemId":"819e1fbf-8b7e-4f6d-811f-693534916a8b","quantity":20,"unitPrice":99.0} -]; - - -const customer = [ - {"_id":"579f21ae98684924944651bf","_class":"works.weave.socks.users.entities.Customer","firstName":"Eve","lastName":"Berger","username":"Eve_Berger","addresses":[{"$ref":"address","$id":ObjectID("579f21ae98684924944651bd")}],"cards":[{"$ref":"card","$id":ObjectID("579f21ae98684924944651be")}] - }, - {"_id":"579f21ae98684924944651c2","_class":"works.weave.socks.users.entities.Customer","firstName":"User","lastName":"Name","username":"user","addresses":[{"$ref":"address","$id":ObjectID("579f21ae98684924944651c0")}],"cards":[{"$ref":"card","$id":ObjectID("579f21ae98684924944651c1")}]}, - {"_id":"579f21ae98684924944651c5","_class":"works.weave.socks.users.entities.Customer","firstName":"User1","lastName":"Name1","username":"user1","addresses":[{"$ref":"address","$id":ObjectID("579f21ae98684924944651c3")}],"cards":[{"$ref":"card","$id":ObjectID("579f21ae98684924944651c4")}]} -]; - - -// Setup database connection before Dredd starts testing -hooks.beforeAll((transactions, done) => { - var MongoEndpoint = process.env.MONGO_ENDPOINT || 'mongodb://localhost:32769/data'; - MongoClient.connect(MongoEndpoint, function(err, conn) { - if (err) { - console.error(err); - } - db = conn; - done(err); - }); -}); - -hooks.beforeEach((transaction, done) => { - db.dropDatabase(function (err, res) { - var promisesToKeep = [ - db.collection('customer').insertMany(customer), - db.collection('card').insertMany(card), - db.collection('cart').insertMany(cart), - db.collection('address').insertMany(address), - db.collection('item').insertMany(item) - ]; - Promise.all(promisesToKeep).then(function(vls) { - done(); - }, function(vls) { - done(); - }); - }) - -}); - - -hooks.before("/carts/{customerId}/items > POST", function(transaction, done) { - transaction.request.headers['Content-Type'] = 'application/json'; - transaction.request.body = JSON.stringify( - { - "itemId":"819e1fbf-8b7e-4f6d-811f-693534916a8b", - "quantity": 20, - "unitPrice" : 99.0 - } - ); - - done(); -}); - -// TODO: Can't make POST and PUT work, skipping for now - -// hooks.before("/carts/{customerId}/items > POST", function(transaction, done) { -// transaction.skip = true; -// done(); -// }); - -hooks.before("/carts/{customerId}/items > PATCH", function(transaction, done) { - transaction.skip = true; - done(); -}); diff --git a/api-spec/mock.json b/api-spec/mock.json deleted file mode 100644 index 080b6de07..000000000 --- a/api-spec/mock.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "carts": [ - { - "id": "57a98d98e4b00679b4a830af" - } - ], - "items": [ - { - "id": 1, - "quantity": 10, - "unitPrice": 1.99, - "cartsId": "57a98d98e4b00679b4a830af" - } - ] -} diff --git a/docker-compose-zipkin.yml b/docker-compose-zipkin.yml deleted file mode 100644 index c467fe3f6..000000000 --- a/docker-compose-zipkin.yml +++ /dev/null @@ -1,37 +0,0 @@ -version: '2' - -services: - carts: - image: weaveworksdemos/carts - hostname: carts - restart: always - cap_drop: - - all - cap_add: - - NET_BIND_SERVICE - read_only: true - tmpfs: - - /tmp:rw,noexec,nosuid - environment: - - reschedule=on-node-failure - - ZIPKIN_HOST=zipkin - - ZIPKIN_ENABLED=true - ports: - - "8081:80" - zipkin: - image: openzipkin/zipkin - hostname: zipkin - restart: always - cap_drop: - - all - cap_add: - - CHOWN - - SETGID - - SETUID - read_only: true - tmpfs: - - /tmp:rw,noexec,nosuid - environment: - - reschedule=on-node-failure - ports: - - "9411:9411" diff --git a/pom.xml b/pom.xml index 8f1ef5182..a9bbd6891 100644 --- a/pom.xml +++ b/pom.xml @@ -14,64 +14,48 @@ org.springframework.boot spring-boot-starter-parent - 2.0.4.RELEASE + 3.2.2 UTF-8 - 1.8 - 0.0.21 + 17 org.springframework.boot - spring-boot-starter-data-rest + spring-boot-properties-migrator + runtime org.springframework.boot - spring-boot-starter-data-mongodb - - - org.springframework.cloud - spring-cloud-starter-zipkin - 1.1.0.RELEASE - - - io.prometheus - simpleclient_spring_boot - ${prometheus.version} - - - io.prometheus - simpleclient_hotspot - ${prometheus.version} + spring-boot-starter-data-rest - io.prometheus - simpleclient_servlet - ${prometheus.version} + org.springframework.boot + spring-boot-starter-test + test - org.springframework.data - spring-data-rest-hal-browser + org.springframework.boot + spring-boot-starter-data-jpa - org.springframework.boot - spring-boot-starter-test - test + jakarta.persistence + jakarta.persistence-api + 3.1.0 - de.flapdoodle.embed - de.flapdoodle.embed.mongo - 1.50.5 - test + org.postgresql + postgresql + 42.7.3 - com.openpojo - openpojo - 0.8.4 - test + org.projectlombok + lombok + 1.18.32 + provided @@ -95,45 +79,6 @@ - - org.apache.maven.plugins - maven-failsafe-plugin - 2.18.1 - - - **/IT*.java - - - **/Unit*.java - - - - - - integration-test - verify - - - - - - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - prepare-agent - - prepare-agent - - - - - - org.eluder.coveralls - coveralls-maven-plugin - 4.2.0 - @@ -142,6 +87,11 @@ spring-releases https://repo.spring.io/libs-release + + maven_central + Maven Central + https://repo.maven.apache.org/maven2/ + @@ -149,4 +99,4 @@ https://repo.spring.io/libs-release - + \ No newline at end of file diff --git a/src/main/java/works/weave/socks/cart/CartApplication.java b/src/main/java/works/weave/socks/cart/CartApplication.java index 51d9a8d45..edef51ae7 100644 --- a/src/main/java/works/weave/socks/cart/CartApplication.java +++ b/src/main/java/works/weave/socks/cart/CartApplication.java @@ -1,11 +1,9 @@ package works.weave.socks.cart; -import io.prometheus.client.spring.boot.EnablePrometheusEndpoint; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -@EnablePrometheusEndpoint public class CartApplication { public static void main(String[] args) { SpringApplication.run(CartApplication.class, args); diff --git a/src/main/java/works/weave/socks/cart/action/FirstResultOrDefault.java b/src/main/java/works/weave/socks/cart/action/FirstResultOrDefault.java deleted file mode 100644 index 73ee1e81f..000000000 --- a/src/main/java/works/weave/socks/cart/action/FirstResultOrDefault.java +++ /dev/null @@ -1,19 +0,0 @@ -package works.weave.socks.cart.action; - -import java.util.Collection; -import java.util.function.Supplier; - -public class FirstResultOrDefault implements Supplier { - private final Collection collection; - private final Supplier nonePresent; - - public FirstResultOrDefault(final Collection collection, final Supplier nonePresent) { - this.collection = collection; - this.nonePresent = nonePresent; - } - - @Override - public T get() { - return collection.stream().findFirst().orElseGet(nonePresent); - } -} diff --git a/src/main/java/works/weave/socks/cart/cart/CartContentsResource.java b/src/main/java/works/weave/socks/cart/cart/CartContentsResource.java deleted file mode 100644 index 05a98c231..000000000 --- a/src/main/java/works/weave/socks/cart/cart/CartContentsResource.java +++ /dev/null @@ -1,47 +0,0 @@ -package works.weave.socks.cart.cart; - -import org.slf4j.Logger; -import works.weave.socks.cart.entities.Cart; -import works.weave.socks.cart.entities.Item; - -import java.util.List; -import java.util.function.Supplier; - -import static org.slf4j.LoggerFactory.getLogger; - -public class CartContentsResource implements Contents { - private final Logger LOG = getLogger(getClass()); - - private final CartDAO cartRepository; - private final Supplier> parent; - - public CartContentsResource(CartDAO cartRepository, Supplier> parent) { - this.cartRepository = cartRepository; - this.parent = parent; - } - - @Override - public Supplier> contents() { - return () -> parentCart().contents(); - } - - @Override - public Runnable add(Supplier item) { - return () -> { - LOG.debug("Adding for user: " + parent.get().value().get().toString() + ", " + item.get()); - cartRepository.save(parentCart().add(item.get())); - }; - } - - @Override - public Runnable delete(Supplier item) { - return () -> { - LOG.debug("Deleting for user: " + parent.get().value().get().toString() + ", " + item.get()); - cartRepository.save(parentCart().remove(item.get())); - }; - } - - private Cart parentCart() { - return parent.get().value().get(); - } -} diff --git a/src/main/java/works/weave/socks/cart/cart/CartDAO.java b/src/main/java/works/weave/socks/cart/cart/CartDAO.java deleted file mode 100644 index 9d921e8e7..000000000 --- a/src/main/java/works/weave/socks/cart/cart/CartDAO.java +++ /dev/null @@ -1,40 +0,0 @@ -package works.weave.socks.cart.cart; - -import works.weave.socks.cart.entities.Cart; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public interface CartDAO { - void delete(Cart cart); - - Cart save(Cart cart); - - List findByCustomerId(String customerId); - - class Fake implements CartDAO { - private Map cartStore = new HashMap<>(); - - @Override - public void delete(Cart cart) { - cartStore.remove(cart.customerId); - } - - @Override - public Cart save(Cart cart) { - return cartStore.put(cart.customerId, cart); - } - - @Override - public List findByCustomerId(String customerId) { - Cart cart = cartStore.get(customerId); - if (cart != null) { - return Collections.singletonList(cart); - } else { - return Collections.emptyList(); - } - } - } -} diff --git a/src/main/java/works/weave/socks/cart/cart/CartResource.java b/src/main/java/works/weave/socks/cart/cart/CartResource.java deleted file mode 100644 index 3f2895262..000000000 --- a/src/main/java/works/weave/socks/cart/cart/CartResource.java +++ /dev/null @@ -1,46 +0,0 @@ -package works.weave.socks.cart.cart; - -import works.weave.socks.cart.action.FirstResultOrDefault; -import works.weave.socks.cart.entities.Cart; - -import java.util.function.Supplier; - -public class CartResource implements Resource, HasContents { - private final CartDAO cartRepository; - private final String customerId; - - public CartResource(CartDAO cartRepository, String customerId) { - this.cartRepository = cartRepository; - this.customerId = customerId; - } - - @Override - public Runnable destroy() { - return () -> cartRepository.delete(value().get()); - } - - @Override - public Supplier create() { - return () -> cartRepository.save(new Cart(customerId)); - } - - @Override - public Supplier value() { - return new FirstResultOrDefault<>( - cartRepository.findByCustomerId(customerId), - () -> { - create().get(); - return value().get(); - }); - } - - @Override - public Runnable merge(Cart toMerge) { - return () -> toMerge.contents().forEach(item -> contents().get().add(() -> item).run()); - } - - @Override - public Supplier contents() { - return () -> new CartContentsResource(cartRepository, () -> this); - } -} diff --git a/src/main/java/works/weave/socks/cart/cart/Contents.java b/src/main/java/works/weave/socks/cart/cart/Contents.java deleted file mode 100644 index 5c68848cd..000000000 --- a/src/main/java/works/weave/socks/cart/cart/Contents.java +++ /dev/null @@ -1,14 +0,0 @@ -package works.weave.socks.cart.cart; - -import works.weave.socks.cart.entities.Item; - -import java.util.List; -import java.util.function.Supplier; - -public interface Contents { - Supplier> contents(); - - Runnable add(Supplier item); - - Runnable delete(Supplier item); -} diff --git a/src/main/java/works/weave/socks/cart/cart/HasContents.java b/src/main/java/works/weave/socks/cart/cart/HasContents.java deleted file mode 100644 index 62052fbe8..000000000 --- a/src/main/java/works/weave/socks/cart/cart/HasContents.java +++ /dev/null @@ -1,7 +0,0 @@ -package works.weave.socks.cart.cart; - -import java.util.function.Supplier; - -public interface HasContents { - Supplier contents(); -} diff --git a/src/main/java/works/weave/socks/cart/cart/Resource.java b/src/main/java/works/weave/socks/cart/cart/Resource.java deleted file mode 100644 index 1c6b269a5..000000000 --- a/src/main/java/works/weave/socks/cart/cart/Resource.java +++ /dev/null @@ -1,47 +0,0 @@ -package works.weave.socks.cart.cart; - -import works.weave.socks.cart.entities.Cart; - -import java.util.function.Supplier; - -public interface Resource { - Runnable destroy(); - - Supplier create(); - - Supplier value(); - - Runnable merge(T toMerge); - - class CartFake implements Resource { - private final String customerId; - private Cart cart = null; - - public CartFake(String customerId) { - this.customerId = customerId; - } - - @Override - public Runnable destroy() { - return () -> cart = null; - } - - @Override - public Supplier create() { - return () -> cart = new Cart(customerId); - } - - @Override - public Supplier value() { - if (cart == null) { - create().get(); - } - return () -> cart; - } - - @Override - public Runnable merge(Cart toMerge) { - return null; - } - } -} diff --git a/src/main/java/works/weave/socks/cart/configuration/BeanConfiguration.java b/src/main/java/works/weave/socks/cart/configuration/BeanConfiguration.java deleted file mode 100644 index 5a9068f5b..000000000 --- a/src/main/java/works/weave/socks/cart/configuration/BeanConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -package works.weave.socks.cart.configuration; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import works.weave.socks.cart.cart.CartDAO; -import works.weave.socks.cart.entities.Cart; -import works.weave.socks.cart.entities.Item; -import works.weave.socks.cart.item.ItemDAO; -import works.weave.socks.cart.repositories.CartRepository; -import works.weave.socks.cart.repositories.ItemRepository; - -import java.util.List; - -@Configuration -public class BeanConfiguration { - @Bean - @Autowired - public CartDAO getCartDao(CartRepository cartRepository) { - return new CartDAO() { - @Override - public void delete(Cart cart) { - cartRepository.delete(cart); - } - - @Override - public Cart save(Cart cart) { - return cartRepository.save(cart); - } - - @Override - public List findByCustomerId(String customerId) { - return cartRepository.findByCustomerId(customerId); - } - }; - } - - @Bean - @Autowired - public ItemDAO getItemDao(ItemRepository itemRepository) { - return new ItemDAO() { - @Override - public Item save(Item item) { - return itemRepository.save(item); - } - - @Override - public void destroy(Item item) { - itemRepository.delete(item); - } - - @Override - public Item findOne(String id) { - return itemRepository.findById(id).orElse(null); - } - }; - } -} diff --git a/src/main/java/works/weave/socks/cart/configuration/MongoConfiguration.java b/src/main/java/works/weave/socks/cart/configuration/MongoConfiguration.java deleted file mode 100644 index 89688859d..000000000 --- a/src/main/java/works/weave/socks/cart/configuration/MongoConfiguration.java +++ /dev/null @@ -1,21 +0,0 @@ -package works.weave.socks.cart.configuration; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.mongodb.MongoClientOptions; - -@Configuration -@AutoConfigureBefore(MongoAutoConfiguration.class) -public class MongoConfiguration { - - @Bean - public MongoClientOptions optionsProvider() { - MongoClientOptions.Builder optionsBuilder = new MongoClientOptions.Builder(); - optionsBuilder.serverSelectionTimeout(10000); - MongoClientOptions options = optionsBuilder.build(); - return options; - } -} diff --git a/src/main/java/works/weave/socks/cart/configuration/ValidationConfiguration.java b/src/main/java/works/weave/socks/cart/configuration/ValidationConfiguration.java deleted file mode 100644 index 248a4fde4..000000000 --- a/src/main/java/works/weave/socks/cart/configuration/ValidationConfiguration.java +++ /dev/null @@ -1,19 +0,0 @@ -package works.weave.socks.cart.configuration; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener; -import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; - -@Configuration -public class ValidationConfiguration { - @Bean - public ValidatingMongoEventListener validatingMongoEventListener() { - return new ValidatingMongoEventListener(validator()); - } - - @Bean - public LocalValidatorFactoryBean validator() { - return new LocalValidatorFactoryBean(); - } -} diff --git a/src/main/java/works/weave/socks/cart/configuration/WebMvcConfig.java b/src/main/java/works/weave/socks/cart/configuration/WebMvcConfig.java deleted file mode 100644 index 7eac966a0..000000000 --- a/src/main/java/works/weave/socks/cart/configuration/WebMvcConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package works.weave.socks.cart.configuration; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.handler.MappedInterceptor; -import works.weave.socks.cart.middleware.HTTPMonitoringInterceptor; - -@Configuration -public class WebMvcConfig { - @Bean - HTTPMonitoringInterceptor httpMonitoringInterceptor() { - return new HTTPMonitoringInterceptor(); - } - - @Bean - public MappedInterceptor myMappedInterceptor(HTTPMonitoringInterceptor interceptor) { - return new MappedInterceptor(new String[]{"/**"}, interceptor); - } -} diff --git a/src/main/java/works/weave/socks/cart/controllers/CartsController.java b/src/main/java/works/weave/socks/cart/controllers/CartsController.java deleted file mode 100644 index 71ef78d4c..000000000 --- a/src/main/java/works/weave/socks/cart/controllers/CartsController.java +++ /dev/null @@ -1,43 +0,0 @@ -package works.weave.socks.cart.controllers; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; -import works.weave.socks.cart.cart.CartDAO; -import works.weave.socks.cart.cart.CartResource; -import works.weave.socks.cart.entities.Cart; - - -@RestController -@RequestMapping(path = "/carts") -public class CartsController { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private CartDAO cartDAO; - - @ResponseStatus(HttpStatus.OK) - @RequestMapping(value = "/{customerId}", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) - public Cart get(@PathVariable String customerId) { - return new CartResource(cartDAO, customerId).value().get(); - } - - @ResponseStatus(HttpStatus.ACCEPTED) - @RequestMapping(value = "/{customerId}", method = RequestMethod.DELETE) - public void delete(@PathVariable String customerId) { - new CartResource(cartDAO, customerId).destroy().run(); - } - - @ResponseStatus(HttpStatus.ACCEPTED) - @RequestMapping(value = "/{customerId}/merge", method = RequestMethod.GET) - public void mergeCarts(@PathVariable String customerId, @RequestParam(value = "sessionId") String sessionId) { - logger.debug("Merge carts request received for ids: " + customerId + " and " + sessionId); - CartResource sessionCart = new CartResource(cartDAO, sessionId); - CartResource customerCart = new CartResource(cartDAO, customerId); - customerCart.merge(sessionCart.value().get()).run(); - delete(sessionId); - } -} diff --git a/src/main/java/works/weave/socks/cart/controllers/HealthCheckController.java b/src/main/java/works/weave/socks/cart/controllers/HealthCheckController.java deleted file mode 100644 index 0025e02e5..000000000 --- a/src/main/java/works/weave/socks/cart/controllers/HealthCheckController.java +++ /dev/null @@ -1,46 +0,0 @@ -package works.weave.socks.cart.controllers; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; -import works.weave.socks.cart.entities.HealthCheck; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@RestController -public class HealthCheckController { - - @Autowired - private MongoTemplate mongoTemplate; - - @ResponseStatus(HttpStatus.OK) - @RequestMapping(method = RequestMethod.GET, path = "/health") - public - @ResponseBody - Map> getHealth() { - Map> map = new HashMap>(); - List healthChecks = new ArrayList(); - Date dateNow = Calendar.getInstance().getTime(); - - HealthCheck app = new HealthCheck("carts", "OK", dateNow); - HealthCheck database = new HealthCheck("carts-db", "OK", dateNow); - - try { - mongoTemplate.executeCommand("{ buildInfo: 1 }"); - } catch (Exception e) { - database.setStatus("err"); - } - - healthChecks.add(app); - healthChecks.add(database); - - map.put("health", healthChecks); - return map; - } -} diff --git a/src/main/java/works/weave/socks/cart/controllers/ItemsController.java b/src/main/java/works/weave/socks/cart/controllers/ItemsController.java index c596aee4e..4f509803d 100644 --- a/src/main/java/works/weave/socks/cart/controllers/ItemsController.java +++ b/src/main/java/works/weave/socks/cart/controllers/ItemsController.java @@ -5,79 +5,74 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; -import works.weave.socks.cart.cart.CartDAO; -import works.weave.socks.cart.cart.CartResource; import works.weave.socks.cart.entities.Item; import works.weave.socks.cart.item.FoundItem; -import works.weave.socks.cart.item.ItemDAO; import works.weave.socks.cart.item.ItemResource; +import works.weave.socks.cart.repositories.ItemRepository; import java.util.List; -import java.util.function.Supplier; import static org.slf4j.LoggerFactory.getLogger; @RestController -@RequestMapping(value = "/carts/{customerId:.*}/items") +@RequestMapping(value = "/carts/{customerId:.*}") public class ItemsController { - private final Logger LOG = getLogger(getClass()); + private final Logger LOG = getLogger(getClass()); - @Autowired - private ItemDAO itemDAO; - @Autowired - private CartsController cartsController; - @Autowired - private CartDAO cartDAO; + @Autowired + ItemRepository itemRepository; - @ResponseStatus(HttpStatus.OK) - @RequestMapping(value = "/{itemId:.*}", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) - public Item get(@PathVariable String customerId, @PathVariable String itemId) { - return new FoundItem(() -> getItems(customerId), () -> new Item(itemId)).get(); - } - - @ResponseStatus(HttpStatus.OK) - @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) - public List getItems(@PathVariable String customerId) { - return cartsController.get(customerId).contents(); - } - @ResponseStatus(HttpStatus.CREATED) - @RequestMapping(consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST) - public Item addToCart(@PathVariable String customerId, @RequestBody Item item) { - // If the item does not exist in the cart, create new one in the repository. - FoundItem foundItem = new FoundItem(() -> cartsController.get(customerId).contents(), () -> item); - if (!foundItem.hasItem()) { - Supplier newItem = new ItemResource(itemDAO, () -> item).create(); - LOG.debug("Did not find item. Creating item for user: " + customerId + ", " + newItem.get()); - new CartResource(cartDAO, customerId).contents().get().add(newItem).run(); - return item; - } else { - Item newItem = new Item(foundItem.get(), foundItem.get().quantity() + 1); - LOG.debug("Found item in cart. Incrementing for user: " + customerId + ", " + newItem); - updateItem(customerId, newItem); - return newItem; - } - } + @ResponseStatus(HttpStatus.OK) + @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) + public Item get(@PathVariable int customerId) { + return new FoundItem(customerId, () -> itemRepository).getByItemId(); + } - @ResponseStatus(HttpStatus.ACCEPTED) - @RequestMapping(value = "/{itemId:.*}", method = RequestMethod.DELETE) - public void removeItem(@PathVariable String customerId, @PathVariable String itemId) { - FoundItem foundItem = new FoundItem(() -> getItems(customerId), () -> new Item(itemId)); - Item item = foundItem.get(); + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = "/items/{itemId:.*}", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) + public Item get(@PathVariable int customerId, @PathVariable int itemId) { + return new FoundItem(customerId, () -> itemRepository).getByItemId(itemId); + } - LOG.debug("Removing item from cart: " + item); - new CartResource(cartDAO, customerId).contents().get().delete(() -> item).run(); + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = "/items", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) + public List getItems(@PathVariable int customerId) { + return new FoundItem(customerId, () -> itemRepository).getByCustomerId(); + } - LOG.debug("Removing item from repository: " + item); - new ItemResource(itemDAO, () -> item).destroy().run(); + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = "/items", consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST) + public Item addToCart(@PathVariable int customerId, @RequestBody Item item) { + try { + FoundItem foundItem = new FoundItem(() -> item, () -> itemRepository); + updateItem(customerId, foundItem.get()); + LOG.debug("Found item in cart. Incrementing for user: {}, {}", customerId, item); + return item; + } catch (NullPointerException e) { + LOG.debug("Did not find item. Creating item for user: {}, {}", customerId, item); + return new ItemResource(itemRepository, () -> item, customerId).create().get(); } + } - @ResponseStatus(HttpStatus.ACCEPTED) - @RequestMapping(consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.PATCH) - public void updateItem(@PathVariable String customerId, @RequestBody Item item) { - // Merge old and new items - ItemResource itemResource = new ItemResource(itemDAO, () -> get(customerId, item.itemId())); - LOG.debug("Merging item in cart for user: " + customerId + ", " + item); - itemResource.merge(item).run(); - } + @ResponseStatus(HttpStatus.ACCEPTED) + @RequestMapping(value = "/items/{itemId:.*}", method = RequestMethod.DELETE) + public void removeItem(@PathVariable int customerId, @PathVariable int itemId) { + LOG.debug("Deleting item: {}", itemId); + new ItemResource(itemRepository, customerId, itemId).destroy().run(); + } + + @ResponseStatus(HttpStatus.ACCEPTED) + @RequestMapping(value = "/items", method = RequestMethod.DELETE) + public void removeItem(@PathVariable int customerId) { + LOG.debug("Deleting item wit cart_id: {}", customerId); + new ItemResource(itemRepository, customerId).destroyByCustomerId().run(); + } + + @ResponseStatus(HttpStatus.ACCEPTED) + @RequestMapping(value = "/items", consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.PATCH) + public void updateItem(@PathVariable int customerId, @RequestBody Item item) { + LOG.debug("Updating item in cart for user: {}, {}", customerId, item); + new ItemResource(itemRepository, () -> item, customerId).update().run(); + } } diff --git a/src/main/java/works/weave/socks/cart/entities/Cart.java b/src/main/java/works/weave/socks/cart/entities/Cart.java deleted file mode 100644 index a4a713d89..000000000 --- a/src/main/java/works/weave/socks/cart/entities/Cart.java +++ /dev/null @@ -1,70 +0,0 @@ -package works.weave.socks.cart.entities; - -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.DBRef; -import org.springframework.data.mongodb.core.mapping.Document; - -import javax.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - -@Document -public class Cart { - @NotNull - public String customerId; // Public instead of getters/setters. - @Id - private String id; - @DBRef - private List items = new ArrayList<>(); - - public Cart(String customerId) { - this.customerId = customerId; - } - - public Cart() { - this(null); - } - - public List contents() { - return items; - } - - public Cart add(Item item) { - items.add(item); - return this; - } - - public Cart remove(Item item) { - items.remove(item); - return this; - } - - @Override - public String toString() { - return "Cart{" + - "id='" + id + '\'' + - ", customerId='" + customerId + '\'' + - ", items=" + items + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Cart cart = (Cart) o; - - if (customerId != null ? !customerId.equals(cart.customerId) : cart.customerId != null) return false; - if (id != null ? !id.equals(cart.id) : cart.id != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = customerId != null ? customerId.hashCode() : 0; - result = 31 * result + (id != null ? id.hashCode() : 0); - return result; - } -} diff --git a/src/main/java/works/weave/socks/cart/entities/HealthCheck.java b/src/main/java/works/weave/socks/cart/entities/HealthCheck.java deleted file mode 100644 index 07f26dd99..000000000 --- a/src/main/java/works/weave/socks/cart/entities/HealthCheck.java +++ /dev/null @@ -1,59 +0,0 @@ -package works.weave.socks.cart.entities; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonFormat; - -import java.util.Calendar; -import java.util.Date; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class HealthCheck { - private String service; - private String status; - - @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSSXXX") - private Date date = Calendar.getInstance().getTime(); - - public HealthCheck() { - - } - - public HealthCheck(String service, String status, Date date) { - this.service = service; - this.status = status; - this.date = date; - } - - @Override - public String toString() { - return "HealthCheck{" + - "service='" + service + '\'' + - ", status='" + status + '\'' + - ", date='" + date + - '}'; - } - - public String getService() { - return service; - } - - public void setService(String service) { - this.service = service; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Date getDate() { - return date; - } - - public void setDate(Date date) { - this.date = date; - } -} diff --git a/src/main/java/works/weave/socks/cart/entities/Item.java b/src/main/java/works/weave/socks/cart/entities/Item.java index 7f45da8e1..a97bcf4ea 100644 --- a/src/main/java/works/weave/socks/cart/entities/Item.java +++ b/src/main/java/works/weave/socks/cart/entities/Item.java @@ -1,63 +1,37 @@ package works.weave.socks.cart.entities; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Document; - -import javax.validation.constraints.NotNull; - -@Document +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.util.Objects; + +@Entity +@Getter +@Setter +@AllArgsConstructor +@Table(name = "cart_items") public class Item { @Id - private String id; + // @GeneratedValue(strategy = GenerationType.) + @Column(name = "cart_id") + private int customerId; + + @Column(name = "item_id") + private int itemId; - @NotNull(message = "Item Id must not be null") - private String itemId; + @Column(name = "quantity") private int quantity; - private float unitPrice; - public Item(String id, String itemId, int quantity, float unitPrice) { - this.id = id; - this.itemId = itemId; - this.quantity = quantity; - this.unitPrice = unitPrice; - } + @Column(name = "price") + private float price; public Item() { - this(null, "", 1, 0F); } - public Item(String itemId) { - this(null, itemId, 1, 0F); - } - - public Item(Item item, String id) { - this(id, item.itemId, item.quantity, item.unitPrice); - } - - public Item(Item item, int quantity) { - this(item.id(), item.itemId, quantity, item.unitPrice); - } - - public String id() { - return id; - } - - public String itemId() { - return itemId; - } - - public int quantity() { - return quantity; - } - - @Override - public String toString() { - return "Item{" + - "id='" + id + '\'' + - ", itemId='" + itemId + '\'' + - ", quantity=" + quantity + - ", unitPrice=" + unitPrice + - '}'; + public int cartId() { + return customerId; } @Override @@ -67,40 +41,6 @@ public boolean equals(Object o) { Item item = (Item) o; - return itemId != null ? itemId.equals(item.itemId) : item.itemId == null; - } - - // ****** Crappy getter/setters for Jackson JSON invoking ******** - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getItemId() { - return itemId; - } - - public void setItemId(String itemId) { - this.itemId = itemId; - } - - public int getQuantity() { - return quantity; - } - - public void setQuantity(int quantity) { - this.quantity = quantity; - } - - public float getUnitPrice() { - return unitPrice; - } - - public void setUnitPrice(float unitPrice) { - this.unitPrice = unitPrice; + return Objects.equals(itemId, item.itemId); } } diff --git a/src/main/java/works/weave/socks/cart/item/FoundItem.java b/src/main/java/works/weave/socks/cart/item/FoundItem.java index 07c5dbaa3..6b82e6879 100644 --- a/src/main/java/works/weave/socks/cart/item/FoundItem.java +++ b/src/main/java/works/weave/socks/cart/item/FoundItem.java @@ -2,6 +2,7 @@ import org.slf4j.Logger; import works.weave.socks.cart.entities.Item; +import works.weave.socks.cart.repositories.ItemRepository; import java.util.List; import java.util.function.Supplier; @@ -9,29 +10,41 @@ import static org.slf4j.LoggerFactory.getLogger; public class FoundItem implements Supplier { - private final Logger LOG = getLogger(getClass()); - private final Supplier> items; - private final Supplier item; - - public FoundItem(Supplier> items, Supplier item) { - this.items = items; - this.item = item; - } - - @Override - public Item get() { - return items.get().stream() - .filter(item.get()::equals) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Cannot find item in cart")); - } - - public boolean hasItem() { - boolean present = items.get().stream() - .filter(item.get()::equals) - .findFirst() - .isPresent(); - LOG.debug((present ? "Found" : "Didn't find") + " item: " + item.get() + ", in: " + items.get()); - return present; - } + private final Logger LOG = getLogger(getClass()); + private Supplier item; + private final Supplier itemRepository; + private int customerId; + + public FoundItem(int customerId, Supplier itemRepository) { + this.customerId = customerId; + this.itemRepository = itemRepository; + } + + public FoundItem(Supplier item, Supplier itemRepository) { + this.item = item; + this.itemRepository = itemRepository; + } + + @Override + public Item get() { + return itemRepository.get().findByItemId(item.get().getItemId()); + } + + public List getByCustomerId() { + return itemRepository.get().findByCustomerId(customerId); + } + + public Item getByItemId() { + return getByCustomerId().stream() + .filter(itemEntry -> itemEntry.getItemId() == item.get().getItemId()) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Cannot find item in db")); + } + + public Item getByItemId(int itemId) { + return getByCustomerId().stream() + .filter(itemEntry -> itemEntry.getItemId() == itemId) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Cannot find item in db")); + } } diff --git a/src/main/java/works/weave/socks/cart/item/ItemDAO.java b/src/main/java/works/weave/socks/cart/item/ItemDAO.java deleted file mode 100644 index 5f66760a0..000000000 --- a/src/main/java/works/weave/socks/cart/item/ItemDAO.java +++ /dev/null @@ -1,35 +0,0 @@ -package works.weave.socks.cart.item; - -import works.weave.socks.cart.entities.Item; - -import java.util.HashMap; -import java.util.Map; - -public interface ItemDAO { - Item save(Item item); - - void destroy(Item item); - - Item findOne(String id); - - class Fake implements ItemDAO { - private Map store = new HashMap<>(); - - @Override - public Item save(Item item) { - return store.put(item.itemId(), item); - } - - @Override - public void destroy(Item item) { - store.remove(item.itemId()); - - } - - @Override - public Item findOne(String id) { - return store.entrySet().stream().filter(i -> i.getValue().id().equals(id)).map(Map.Entry::getValue) - .findFirst().orElse(null); - } - } -} diff --git a/src/main/java/works/weave/socks/cart/item/ItemResource.java b/src/main/java/works/weave/socks/cart/item/ItemResource.java index 1753f2a13..f85d8c129 100644 --- a/src/main/java/works/weave/socks/cart/item/ItemResource.java +++ b/src/main/java/works/weave/socks/cart/item/ItemResource.java @@ -1,36 +1,78 @@ package works.weave.socks.cart.item; -import works.weave.socks.cart.cart.Resource; import works.weave.socks.cart.entities.Item; +import works.weave.socks.cart.repositories.ItemRepository; import java.util.function.Supplier; public class ItemResource implements Resource { - private final ItemDAO itemRepository; - private final Supplier item; - - public ItemResource(ItemDAO itemRepository, Supplier item) { - this.itemRepository = itemRepository; - this.item = item; - } - - @Override - public Runnable destroy() { - return () -> itemRepository.destroy(value().get()); - } - - @Override - public Supplier create() { - return () -> itemRepository.save(item.get()); - } - - @Override - public Supplier value() { - return item; // Basically a null method. Gets the item from the supplier. - } - - @Override - public Runnable merge(Item toMerge) { - return () -> itemRepository.save(new Item(value().get(), toMerge.quantity())); - } + private final ItemRepository itemRepository; + private Supplier item; + private final int customerId; + private int itemId; + + public ItemResource(ItemRepository itemRepository, int customerId) { + this.itemRepository = itemRepository; + this.customerId = customerId; + } + + public ItemResource(ItemRepository itemRepository, int customerId, int itemId) { + this.itemRepository = itemRepository; + this.customerId = customerId; + this.itemId = itemId; + } + + public ItemResource(ItemRepository itemRepository, Supplier item, int customerId) { + this.itemRepository = itemRepository; + this.item = item; + this.customerId = customerId; + } + + public Runnable destroyByCustomerId() { + return () -> itemRepository.deleteByCustomerId(customerId); + } + + @Override + public Runnable destroy() { + return () -> itemRepository.deleteByCustomerIdAndItemId( + customerId, + itemId + ); + } + + @Override + public Supplier value() { + return null; + } + + @Override + public Supplier create() { + return () -> { + try { + return itemRepository.save(new Item( + customerId, + item.get().getItemId(), + item.get().getQuantity(), + item.get().getPrice() + )); + } catch (NullPointerException e) { + return itemRepository.save(new Item( + item.get().cartId(), + item.get().getItemId(), + 0, + 0 + )); + } + }; + } + + @Override + public Runnable update() { + return () -> itemRepository.updateAllByCustomerId( + customerId, + item.get().getItemId(), + item.get().getQuantity(), + item.get().getPrice() + ); + } } diff --git a/src/main/java/works/weave/socks/cart/item/Resource.java b/src/main/java/works/weave/socks/cart/item/Resource.java new file mode 100644 index 000000000..5a6c03f9b --- /dev/null +++ b/src/main/java/works/weave/socks/cart/item/Resource.java @@ -0,0 +1,13 @@ +package works.weave.socks.cart.item; + +import java.util.function.Supplier; + +public interface Resource { + Runnable destroy(); + + Supplier value(); + + Supplier create(); + + Runnable update(); +} \ No newline at end of file diff --git a/src/main/java/works/weave/socks/cart/middleware/HTTPMonitoringInterceptor.java b/src/main/java/works/weave/socks/cart/middleware/HTTPMonitoringInterceptor.java deleted file mode 100644 index 728b3423f..000000000 --- a/src/main/java/works/weave/socks/cart/middleware/HTTPMonitoringInterceptor.java +++ /dev/null @@ -1,100 +0,0 @@ -package works.weave.socks.cart.middleware; - -import io.prometheus.client.Histogram; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ApplicationContext; -import org.springframework.data.rest.core.config.RepositoryRestConfiguration; -import org.springframework.data.rest.core.mapping.ResourceMappings; -import org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping; -import org.springframework.data.rest.webmvc.support.JpaHelper; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.HashSet; -import java.util.Set; - -public class HTTPMonitoringInterceptor implements HandlerInterceptor { - static final Histogram requestLatency = Histogram.build() - .name("http_request_duration_seconds") - .help("Request duration in seconds.") - .labelNames("service", "method", "path", "status_code") - .register(); - - private static final String startTimeKey = "startTime"; - @Autowired - ResourceMappings mappings; - @Autowired - JpaHelper jpaHelper; - @Autowired - RepositoryRestConfiguration repositoryConfiguration; - @Autowired - ApplicationContext applicationContext; - @Autowired - RequestMappingHandlerMapping requestMappingHandlerMapping; - private Set urlPatterns; - @Value("${spring.application.name:orders}") - private String serviceName; - - @Override - public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse - httpServletResponse, Object o) throws Exception { - httpServletRequest.setAttribute(startTimeKey, System.nanoTime()); - return true; - } - - @Override - public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse - httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { - long start = (long) httpServletRequest.getAttribute(startTimeKey); - long elapsed = System.nanoTime() - start; - double seconds = (double) elapsed / 1000000000.0; - String matchedUrl = getMatchingURLPattern(httpServletRequest); - if (!matchedUrl.equals("")) { - requestLatency.labels( - serviceName, - httpServletRequest.getMethod(), - matchedUrl, - Integer.toString(httpServletResponse.getStatus()) - ).observe(seconds); - } - } - - @Override - public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse - httpServletResponse, Object o, Exception e) throws Exception { - } - - private String getMatchingURLPattern(HttpServletRequest httpServletRequest) { - String res = ""; - for (PatternsRequestCondition pattern : getUrlPatterns()) { - if (pattern.getMatchingCondition(httpServletRequest) != null && - !httpServletRequest.getServletPath().equals("/error")) { - res = pattern.getMatchingCondition(httpServletRequest).getPatterns().iterator() - .next(); - break; - } - } - return res; - } - - private Set getUrlPatterns() { - if (this.urlPatterns == null) { - this.urlPatterns = new HashSet<>(); - requestMappingHandlerMapping.getHandlerMethods().forEach((mapping, handlerMethod) -> - urlPatterns.add(mapping.getPatternsCondition())); - RepositoryRestHandlerMapping repositoryRestHandlerMapping = new - RepositoryRestHandlerMapping(mappings, repositoryConfiguration); - repositoryRestHandlerMapping.setJpaHelper(jpaHelper); - repositoryRestHandlerMapping.setApplicationContext(applicationContext); - repositoryRestHandlerMapping.afterPropertiesSet(); - repositoryRestHandlerMapping.getHandlerMethods().forEach((mapping, handlerMethod) -> - urlPatterns.add(mapping.getPatternsCondition())); - } - return this.urlPatterns; - } -} diff --git a/src/main/java/works/weave/socks/cart/repositories/CartRepository.java b/src/main/java/works/weave/socks/cart/repositories/CartRepository.java deleted file mode 100644 index 47c68d997..000000000 --- a/src/main/java/works/weave/socks/cart/repositories/CartRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package works.weave.socks.cart.repositories; - -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.data.repository.query.Param; -import org.springframework.data.rest.core.annotation.RepositoryRestResource; -import works.weave.socks.cart.entities.Cart; - -import java.util.List; - -@RepositoryRestResource(exported = false) -public interface CartRepository extends MongoRepository { - List findByCustomerId(@Param("custId") String id); -} - diff --git a/src/main/java/works/weave/socks/cart/repositories/ItemRepository.java b/src/main/java/works/weave/socks/cart/repositories/ItemRepository.java index 0c832818a..1cb8b8e9d 100644 --- a/src/main/java/works/weave/socks/cart/repositories/ItemRepository.java +++ b/src/main/java/works/weave/socks/cart/repositories/ItemRepository.java @@ -1,10 +1,31 @@ package works.weave.socks.cart.repositories; -import org.springframework.data.mongodb.repository.MongoRepository; +import jakarta.transaction.Transactional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.data.rest.core.annotation.RepositoryRestResource; import works.weave.socks.cart.entities.Item; +import java.util.List; + @RepositoryRestResource -public interface ItemRepository extends MongoRepository { -} +@Transactional +public interface ItemRepository extends JpaRepository { + Item findByItemId(@Param("itemId") int itemId); + + List findByCustomerId(@Param("customerId") int customerId); + @Modifying + @Query("UPDATE Item i SET i.quantity = ?3, i.price = ?4 WHERE i.customerId = ?1 AND i.itemId = ?2") + void updateAllByCustomerId(int customerId, int itemId, int quantity, float price); + + @Modifying + @Query("DELETE FROM Item i where i.customerId = ?1 AND i.itemId = ?2") + void deleteByCustomerIdAndItemId(int customerId, int itemId); + + @Modifying + @Query("DELETE FROM Item i where i.customerId = ?1") + void deleteByCustomerId(int customerId); +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3f23d3469..0e75dd72a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,10 +1,9 @@ server.port=${port:8081} -spring.data.mongodb.uri=mongodb://${db:carts-db}:27017/data -endpoints.health.enabled=false -spring.zipkin.baseUrl=http://${zipkin_host:zipkin}:9411/ -spring.zipkin.enabled=${zipkin_enabled:false} -spring.sleuth.sampler.percentage=1.0 -spring.application.name=carts -# Disable actuator metrics endpoints -endpoints.metrics.enabled=false -endpoints.prometheus.id=metrics + +spring.jpa.hibernate.ddl-auto=none +spring.jpa.properties.hibernate.format_sql=true +spring.datasource.url=jdbc:postgresql://localhost:5432/products?currentSchema=cart +spring.datasource.username=myuser +spring.datasource.password=p05tgr3$ + +spring.application.name=carts \ No newline at end of file diff --git a/src/test/java/works/weave/socks/cart/action/UnitFirstResultOrDefault.java b/src/test/java/works/weave/socks/cart/action/UnitFirstResultOrDefault.java deleted file mode 100644 index b2834b118..000000000 --- a/src/test/java/works/weave/socks/cart/action/UnitFirstResultOrDefault.java +++ /dev/null @@ -1,33 +0,0 @@ -package works.weave.socks.cart.action; - -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; - -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertThat; - -public class UnitFirstResultOrDefault { - @Test - public void whenEmptyUsesDefault() { - String defaultValue = "test"; - FirstResultOrDefault CUT = new FirstResultOrDefault<>(Collections.emptyList(), () -> defaultValue); - assertThat(CUT.get(), equalTo(defaultValue)); - } - - @Test - public void whenNotEmptyUseFirst() { - String testValue = "test"; - FirstResultOrDefault CUT = new FirstResultOrDefault<>(Arrays.asList(testValue), () -> "nonDefault"); - assertThat(CUT.get(), equalTo(testValue)); - } - - @Test - public void whenMultipleNotEmptyUseFirst() { - String testValue = "test"; - FirstResultOrDefault CUT = new FirstResultOrDefault<>(Arrays.asList(testValue, "test2"), () -> - "nonDefault"); - assertThat(CUT.get(), equalTo(testValue)); - } -} diff --git a/src/test/java/works/weave/socks/cart/cart/UnitCartContentsResource.java b/src/test/java/works/weave/socks/cart/cart/UnitCartContentsResource.java deleted file mode 100644 index 9d17e7742..000000000 --- a/src/test/java/works/weave/socks/cart/cart/UnitCartContentsResource.java +++ /dev/null @@ -1,42 +0,0 @@ -package works.weave.socks.cart.cart; - -import org.hamcrest.collection.IsCollectionWithSize; -import org.junit.Test; -import works.weave.socks.cart.entities.Cart; -import works.weave.socks.cart.entities.Item; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; - -public class UnitCartContentsResource { - private final String customerId = "testId"; - private final CartDAO.Fake fakeDAO = new CartDAO.Fake(); - private final Resource fakeCartResource = new Resource.CartFake(customerId); - - @Test - public void shouldAddAndReturnContents() { - CartContentsResource contentsResource = new CartContentsResource(fakeDAO, () -> fakeCartResource); - Item item = new Item("testId"); - contentsResource.add(() -> item).run(); - assertThat(contentsResource.contents().get(), IsCollectionWithSize.hasSize(1)); - assertThat(contentsResource.contents().get(), containsInAnyOrder(item)); - } - - @Test - public void shouldStartEmpty() { - CartContentsResource contentsResource = new CartContentsResource(fakeDAO, () -> fakeCartResource); - assertThat(contentsResource.contents().get(), IsCollectionWithSize.hasSize(0)); - } - - @Test - public void shouldDeleteItemFromCart() { - CartContentsResource contentsResource = new CartContentsResource(fakeDAO, () -> fakeCartResource); - Item item = new Item("testId"); - contentsResource.add(() -> item).run(); - assertThat(contentsResource.contents().get(), IsCollectionWithSize.hasSize(1)); - assertThat(contentsResource.contents().get(), containsInAnyOrder(item)); - Item item2 = new Item(item.itemId()); - contentsResource.delete(() -> item2).run(); - assertThat(contentsResource.contents().get(), IsCollectionWithSize.hasSize(0)); - } -} diff --git a/src/test/java/works/weave/socks/cart/cart/UnitCartResource.java b/src/test/java/works/weave/socks/cart/cart/UnitCartResource.java deleted file mode 100644 index 674f3b4b9..000000000 --- a/src/test/java/works/weave/socks/cart/cart/UnitCartResource.java +++ /dev/null @@ -1,83 +0,0 @@ -package works.weave.socks.cart.cart; - -import org.junit.Test; -import works.weave.socks.cart.entities.Cart; -import works.weave.socks.cart.entities.Item; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.Matchers.anyOf; -import static org.hamcrest.Matchers.*; -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertThat; - -public class UnitCartResource { - - private final String customerId = "testId"; - private final CartDAO.Fake fake = new CartDAO.Fake(); - - @Test - public void whenCartExistsUseThat() { - Cart cart = new Cart(customerId); - fake.save(cart); - CartResource cartResource = new CartResource(fake, customerId); - assertThat(cartResource.value().get(), equalTo(cart)); - } - - @Test - public void whenCartDoesntExistCreateNew() { - CartResource cartResource = new CartResource(fake, customerId); - assertThat(cartResource.value().get(), is(notNullValue())); - assertThat(cartResource.value().get().customerId, is(equalTo(customerId))); - } - - @Test - public void whenDestroyRemoveItem() { - Cart cart = new Cart(customerId); - fake.save(cart); - CartResource cartResource = new CartResource(fake, customerId); - cartResource.destroy().run(); - assertThat(fake.findByCustomerId(customerId), is(empty())); - } - - @Test - public void whenDestroyOnEmptyStillEmpty() { - CartResource cartResource = new CartResource(fake, customerId); - cartResource.destroy().run(); - assertThat(fake.findByCustomerId(customerId), is(empty())); - } - - @Test - public void whenCreateDoCreate() { - CartResource cartResource = new CartResource(fake, customerId); - cartResource.create().get(); - assertThat(fake.findByCustomerId(customerId), is(not(empty()))); - } - - @Test - public void contentsShouldBeEmptyWhenNew() { - CartResource cartResource = new CartResource(fake, customerId); - cartResource.create().get(); - assertThat(cartResource.contents().get().contents().get(), is(empty())); - } - - @Test - public void mergedItemsShouldBeInCart() { - String person1 = "person1"; - String person2 = "person2"; - Item person1Item = new Item("item1"); - Item person2Item = new Item("item2"); - CartResource cartResource = new CartResource(fake, person1); - cartResource.contents().get().add(() -> person1Item).run(); - CartResource cartResourceToMerge = new CartResource(fake, person2); - cartResourceToMerge.contents().get().add(() -> person2Item).run(); - cartResource.merge(cartResourceToMerge.value().get()).run(); - assertThat(cartResource.contents().get().contents().get(), hasSize(2)); - assertThat(cartResource.contents().get().contents().get().get(0), anyOf(equalTo(person1Item), equalTo - (person2Item))); - assertThat(cartResource.contents().get().contents().get().get(1), anyOf(equalTo(person1Item), equalTo - (person2Item))); - assertThat(cartResourceToMerge.contents().get().contents().get(), hasSize(1)); - } -} diff --git a/src/test/java/works/weave/socks/cart/controllers/UnitCartsController.java b/src/test/java/works/weave/socks/cart/controllers/UnitCartsController.java deleted file mode 100644 index 274dc8233..000000000 --- a/src/test/java/works/weave/socks/cart/controllers/UnitCartsController.java +++ /dev/null @@ -1,96 +0,0 @@ -package works.weave.socks.cart.controllers; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import works.weave.socks.cart.cart.CartDAO; -import works.weave.socks.cart.entities.Cart; -import works.weave.socks.cart.entities.Item; -import works.weave.socks.cart.item.ItemDAO; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.hamcrest.collection.IsEmptyCollection.empty; -import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; -import static org.junit.Assert.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -public class UnitCartsController { - - @Autowired - private ItemsController itemsController; - - @Autowired - private CartDAO cartDAO; - - @Autowired - private CartsController cartsController; - - - @Test - public void shouldGetCart() { - String customerId = "customerIdGet"; - Cart cart = new Cart(customerId); - cartDAO.save(cart); - Cart gotCart = cartsController.get(customerId); - assertThat(gotCart, is(equalTo(cart))); - assertThat(cartDAO.findByCustomerId(customerId).get(0), is(equalTo(cart))); - } - - @Test - public void shouldDeleteCart() { - String customerId = "customerIdGet"; - Cart cart = new Cart(customerId); - cartDAO.save(cart); - cartsController.delete(customerId); - assertThat(cartDAO.findByCustomerId(customerId), is(empty())); - } - - @Test - public void shouldMergeItemsInCartsTogether() { - String customerId1 = "customerId1"; - Cart cart1 = new Cart(customerId1); - Item itemId1 = new Item("itemId1"); - cart1.add(itemId1); - cartDAO.save(cart1); - String customerId2 = "customerId2"; - Cart cart2 = new Cart(customerId2); - Item itemId2 = new Item("itemId2"); - cart2.add(itemId2); - cartDAO.save(cart2); - - cartsController.mergeCarts(customerId1, customerId2); - assertThat(cartDAO.findByCustomerId(customerId1).get(0).contents(), is(hasSize(2))); - assertThat(cartDAO.findByCustomerId(customerId1).get(0).contents(), is(containsInAnyOrder(itemId1, itemId2))); - assertThat(cartDAO.findByCustomerId(customerId2), is(empty())); - } - - @Configuration - static class ItemsControllerTestConfiguration { - @Bean - public ItemsController itemsController() { - return new ItemsController(); - } - - @Bean - public CartsController cartsController() { - return new CartsController(); - } - - @Bean - public ItemDAO itemDAO() { - return new ItemDAO.Fake(); - } - - @Bean - public CartDAO cartDAO() { - return new CartDAO.Fake(); - } - } -} diff --git a/src/test/java/works/weave/socks/cart/controllers/UnitHealthCheckController.java b/src/test/java/works/weave/socks/cart/controllers/UnitHealthCheckController.java deleted file mode 100644 index 97b30ff57..000000000 --- a/src/test/java/works/weave/socks/cart/controllers/UnitHealthCheckController.java +++ /dev/null @@ -1,51 +0,0 @@ -package works.weave.socks.cart.controllers; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.*; -import works.weave.socks.cart.entities.HealthCheck; - - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -public class UnitHealthCheckController { - - @Autowired - private HealthCheckController healthCheckController; - - @Test - public void shouldGetHealth() { - Map> results = this.healthCheckController.getHealth(); - assertThat(results.get("health").size(), is(equalTo(2))); - } - - @Configuration - static class HealthCheckControllerTestConfiguration { - @Bean - public HealthCheckController healthCheckController() { - return new HealthCheckController(); - } - - @Bean - public MongoTemplate mongoTemplate() { - MongoTemplate mongoTemplate = mock(MongoTemplate.class); - return mongoTemplate; - } - } -} diff --git a/src/test/java/works/weave/socks/cart/controllers/UnitItemsController.java b/src/test/java/works/weave/socks/cart/controllers/UnitItemsController.java deleted file mode 100644 index ba07440e7..000000000 --- a/src/test/java/works/weave/socks/cart/controllers/UnitItemsController.java +++ /dev/null @@ -1,95 +0,0 @@ -package works.weave.socks.cart.controllers; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import works.weave.socks.cart.cart.CartDAO; -import works.weave.socks.cart.entities.Item; -import works.weave.socks.cart.item.ItemDAO; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.junit.Assert.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -public class UnitItemsController { - - @Autowired - private ItemsController itemsController; - - @Autowired - private ItemDAO itemDAO; - - @Autowired - private CartsController cartsController; - - @Test - public void whenNewItemAdd() { - Item item = new Item("id", "itemId", 1, 0F); - String customerId = "customerIdAdd"; - itemsController.addToCart(customerId, item); - assertThat(itemsController.getItems(customerId), is(hasSize(1))); - assertThat(itemsController.getItems(customerId), is(org.hamcrest.CoreMatchers.hasItem(item))); - } - - @Test - public void whenExistIncrementQuantity() { - Item item = new Item("id", "itemId", 1, 0F); - String customerId = "customerIdIncrement"; - itemsController.addToCart(customerId, item); - itemsController.addToCart(customerId, item); - assertThat(itemsController.getItems(customerId), is(hasSize(1))); - assertThat(itemsController.getItems(customerId), is(org.hamcrest.CoreMatchers.hasItem(item))); - assertThat(itemDAO.findOne(item.id()).quantity(), is(equalTo(2))); - } - - @Test - public void shouldRemoveItemFromCart() { - Item item = new Item("id", "itemId", 1, 0F); - String customerId = "customerIdRemove"; - itemsController.addToCart(customerId, item); - assertThat(itemsController.getItems(customerId), is(hasSize(1))); - itemsController.removeItem(customerId, item.itemId()); - assertThat(itemsController.getItems(customerId), is(hasSize(0))); - } - - @Test - public void shouldSetQuantity() { - Item item = new Item("id", "itemId", 1, 0F); - String customerId = "customerIdQuantity"; - itemsController.addToCart(customerId, item); - assertThat(itemsController.getItems(customerId).get(0).quantity(), is(equalTo(item.quantity()))); - Item anotherItem = new Item(item, 15); - itemsController.updateItem(customerId, anotherItem); - assertThat(itemDAO.findOne(item.id()).quantity(), is(equalTo(anotherItem.quantity()))); - } - - @Configuration - static class ItemsControllerTestConfiguration { - @Bean - public ItemsController itemsController() { - return new ItemsController(); - } - - @Bean - public CartsController cartsController() { - return new CartsController(); - } - - @Bean - public ItemDAO itemDAO() { - return new ItemDAO.Fake(); - } - - @Bean - public CartDAO cartDAO() { - return new CartDAO.Fake(); - } - } -} diff --git a/src/test/java/works/weave/socks/cart/item/UnitFoundItem.java b/src/test/java/works/weave/socks/cart/item/UnitFoundItem.java deleted file mode 100644 index 70ae862f3..000000000 --- a/src/test/java/works/weave/socks/cart/item/UnitFoundItem.java +++ /dev/null @@ -1,23 +0,0 @@ -package works.weave.socks.cart.item; - -import org.junit.Test; -import works.weave.socks.cart.entities.Item; - -import java.util.ArrayList; -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertThat; - -public class UnitFoundItem { - @Test - public void findOneItem() { - List list = new ArrayList<>(); - String testId = "testId"; - Item testAnswer = new Item(testId); - list.add(testAnswer); - FoundItem foundItem = new FoundItem(() -> list, () -> testAnswer); - assertThat(foundItem.get(), is(equalTo(testAnswer))); - } -} diff --git a/src/test/java/works/weave/socks/cart/item/UnitItemResource.java b/src/test/java/works/weave/socks/cart/item/UnitItemResource.java deleted file mode 100644 index 068d9500b..000000000 --- a/src/test/java/works/weave/socks/cart/item/UnitItemResource.java +++ /dev/null @@ -1,34 +0,0 @@ -package works.weave.socks.cart.item; - -import org.junit.Test; -import works.weave.socks.cart.entities.Item; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertThat; - - -public class UnitItemResource { - private ItemDAO itemDAO = new ItemDAO.Fake(); - - @Test - public void testCreateAndDestroy() { - Item item = new Item("itemId", "testId", 1, 0F); - ItemResource itemResource = new ItemResource(itemDAO, () -> item); - itemResource.create().get(); - assertThat(itemDAO.findOne(item.id()), is(equalTo(item))); - itemResource.destroy().run(); - assertThat(itemDAO.findOne(item.id()), is(nullValue())); - } - - @Test - public void mergedItemShouldHaveNewQuantity() { - Item item = new Item("itemId", "testId", 1, 0F); - ItemResource itemResource = new ItemResource(itemDAO, () -> item); - assertThat(itemResource.value().get(), is(equalTo(item))); - Item newItem = new Item(item, 10); - itemResource.merge(newItem).run(); - assertThat(itemDAO.findOne(item.id()).quantity(), is(equalTo(newItem.quantity()))); - } -} diff --git a/src/test/java/works/weave/socks/cart/repositories/ITCartRepository.java b/src/test/java/works/weave/socks/cart/repositories/ITCartRepository.java deleted file mode 100644 index a0f3d6d1a..000000000 --- a/src/test/java/works/weave/socks/cart/repositories/ITCartRepository.java +++ /dev/null @@ -1,53 +0,0 @@ -package works.weave.socks.cart.repositories; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.test.context.junit4.SpringRunner; -import works.weave.socks.cart.entities.Cart; - -import java.util.List; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@EnableAutoConfiguration -public class ITCartRepository { - @Autowired - private CartRepository cartRepository; - - @Before - public void removeAllData() { - cartRepository.deleteAll(); - } - - @Test - public void testCartSave() { - Cart original = new Cart("customerId"); - Cart saved = cartRepository.save(original); - - assertEquals(1, cartRepository.count()); - assertEquals(original, saved); - } - - @Test - public void testCartGetDefault() { - Cart original = new Cart("customerId"); - Cart saved = cartRepository.save(original); - - assertEquals(1, cartRepository.count()); - assertEquals(original, saved); - } - - @Test - public void testSearchCustomerById() { - Cart original = new Cart("customerId"); - cartRepository.save(original); - - List found = cartRepository.findByCustomerId(original.customerId); - assertEquals(1, found.size()); - assertEquals(original, found.get(0)); - } -} diff --git a/src/test/java/works/weave/socks/cart/repositories/ITItemRepository.java b/src/test/java/works/weave/socks/cart/repositories/ITItemRepository.java deleted file mode 100644 index 93bb87afb..000000000 --- a/src/test/java/works/weave/socks/cart/repositories/ITItemRepository.java +++ /dev/null @@ -1,32 +0,0 @@ -package works.weave.socks.cart.repositories; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.test.context.junit4.SpringRunner; -import works.weave.socks.cart.entities.Item; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@EnableAutoConfiguration -public class ITItemRepository { - @Autowired - private ItemRepository itemRepository; - - @Before - public void removeAllData() { - itemRepository.deleteAll(); - } - - @Test - public void testCustomerSave() { - Item original = new Item("id", "itemId", 1, 0.99F); - Item saved = itemRepository.save(original); - - assertEquals(1, itemRepository.count()); - assertEquals(original, saved); - } -} diff --git a/test/Dockerfile b/test/Dockerfile deleted file mode 100644 index 8b921b33d..000000000 --- a/test/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM python:3.6-alpine - -RUN apk add --no-cache \ - ca-certificates \ - curl \ - openssl - -ENV DOCKER_BUCKET get.docker.com -ENV DOCKER_VERSION 1.8.3 - -RUN set -x \ - && curl -fSL "https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz" -o docker.tgz \ - && tar -xzvf docker.tgz \ - && docker -v - -RUN pip install requests diff --git a/test/component.py b/test/component.py deleted file mode 100644 index f2ec93887..000000000 --- a/test/component.py +++ /dev/null @@ -1,19 +0,0 @@ -import os -import unittest -from os.path import expanduser - -from util.Docker import Docker - - -class JavaServices(unittest.TestCase): - def test_maven(self): - script_dir = os.path.dirname(os.path.realpath(__file__)) - code_dir = script_dir + "/.." - home = expanduser("~") - command = ['docker', 'run', '--rm', '-v', home + '/.m2:/root/.m2', '-v', code_dir + ':/usr/src/mymaven', '-w', - '/usr/src/mymaven', 'maven:3.6-jdk-11', 'mvn', 'integration-test'] - print(Docker().execute(command)) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/container.py b/test/container.py deleted file mode 100644 index bde4494a3..000000000 --- a/test/container.py +++ /dev/null @@ -1,67 +0,0 @@ -import argparse -import sys -import unittest -import os -from util.Api import Api -from time import sleep - -from util.Docker import Docker -from util.Dredd import Dredd - -class CartContainerTest(unittest.TestCase): - TAG = "latest" - COMMIT = "" - container_name = Docker().random_container_name('carts') - mongo_container_name = Docker().random_container_name('carts-db') - def __init__(self, methodName='runTest'): - super(CartContainerTest, self).__init__(methodName) - self.ip = "" - - def setUp(self): - Docker().start_container(container_name=self.mongo_container_name, image="mongo", host="carts-db") - command = ['docker', 'run', - '-d', - '--name', CartContainerTest.container_name, - '-h', 'carts', - '--link', - CartContainerTest.mongo_container_name, - 'weaveworksdemos/carts:' + self.COMMIT] - Docker().execute(command) - self.ip = Docker().get_container_ip(CartContainerTest.container_name) - - def tearDown(self): - Docker().kill_and_remove(CartContainerTest.container_name) - Docker().kill_and_remove(CartContainerTest.mongo_container_name) - - def test_api_validated(self): - limit = 30 - while Api().noResponse('http://' + self.ip + ':80/carts/'): - if limit == 0: - self.fail("Couldn't get the API running") - limit = limit - 1 - sleep(1) - - out = Dredd().test_against_endpoint( - "carts", "http://carts/", - links=[self.mongo_container_name, self.container_name], - env=[("MONGO_ENDPOINT", "mongodb://carts-db:27017/data")], - dump_streams=True) - self.assertGreater(out.find("0 failing"), -1) - self.assertGreater(out.find("0 errors"), -1) - print(out) - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - default_tag = "latest" - parser.add_argument('--tag', default=default_tag, help='The tag of the image to use. (default: latest)') - parser.add_argument('unittest_args', nargs='*') - args = parser.parse_args() - CartContainerTest.TAG = args.tag - - if CartContainerTest.TAG == "": - CartContainerTest.TAG = default_tag - - CartContainerTest.COMMIT = os.environ["COMMIT"] - # Now set the sys.argv to the unittest_args (leaving sys.argv[0] alone) - sys.argv[1:] = args.unittest_args - unittest.main() diff --git a/test/coveralls.py b/test/coveralls.py deleted file mode 100644 index 8109e95be..000000000 --- a/test/coveralls.py +++ /dev/null @@ -1,36 +0,0 @@ -import os -import unittest -from os.path import expanduser - -from util.Docker import Docker - - -class JavaServices(unittest.TestCase): - def test_maven(self): - script_dir = os.path.dirname(os.path.realpath(__file__)) - code_dir = script_dir + "/.." - home = expanduser("~") - command = ['docker', 'run', '--rm', - '-v', home + '/.m2:/root/.m2', - '-v', code_dir + ':/usr/src/mymaven', - '-w', '/usr/src/mymaven', - 'maven:3.6-jdk-11', - 'mvn', - '-DrepoToken=' + os.getenv('COVERALLS_TOKEN'), - '-DserviceJobId=' + os.getenv('TRAVIS_JOB_ID'), - '-Dbranch=' + os.getenv('TRAVIS_BRANCH'), - '-DpullRequest=' + os.getenv('TRAVIS_PULL_REQUEST'), - '-DserviceName=' + os.getenv('TRAVIS'), - 'verify', - 'jacoco:report', - 'coveralls:report'] - print("Coveralls command: ", - '-DserviceJobId=' + os.getenv('TRAVIS_JOB_ID'), - '-Dbranch=' + os.getenv('TRAVIS_BRANCH'), - '-DpullRequest=' + os.getenv('TRAVIS_PULL_REQUEST'), - '-DserviceName=' + 'TRAVIS') - print(Docker().execute(command)) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/test.sh b/test/test.sh deleted file mode 100755 index 13adbeec1..000000000 --- a/test/test.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -set -ev - -SCRIPT_DIR=`dirname "$0"` -SCRIPT_NAME=`basename "$0"` -SSH_OPTS=-oStrictHostKeyChecking=no - -if [[ "$(uname)" == "Darwin" ]]; then - DOCKER_CMD=docker -else - DOCKER_CMD="sudo docker" -fi - -if [[ -z $($DOCKER_CMD images | grep test-container) ]] ; then - echo "Building test container" - docker build -t test-container $SCRIPT_DIR > /dev/null -fi - -echo "Testing $1" -CODE_DIR=$(cd $SCRIPT_DIR/..; pwd) -echo "$@" -$DOCKER_CMD run \ - --rm \ - --name test \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v $CODE_DIR:$CODE_DIR -w $CODE_DIR \ - -e COVERALLS_TOKEN=$COVERALLS_TOKEN \ - -e TRAVIS_JOB_ID=$TRAVIS_JOB_ID \ - -e TRAVIS_BRANCH=$TRAVIS_BRANCH \ - -e TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST \ - -e TRAVIS=$TRAVIS \ - -e TAG=$TAG \ - -e COMMIT=$COMMIT \ - test-container \ - sh -c "export PYTHONPATH=\$PYTHONPATH:\$PWD/test ; python test/$@" diff --git a/test/unit.py b/test/unit.py deleted file mode 100644 index 8ede38f05..000000000 --- a/test/unit.py +++ /dev/null @@ -1,19 +0,0 @@ -import os -import unittest -from os.path import expanduser - -from util.Docker import Docker - - -class JavaServices(unittest.TestCase): - def test_maven(self): - script_dir = os.path.dirname(os.path.realpath(__file__)) - code_dir = script_dir + "/.." - home = expanduser("~") - command = ['docker', 'run', '--rm', '-v', home + '/.m2:/root/.m2', '-v', code_dir + ':/usr/src/mymaven', '-w', - '/usr/src/mymaven', 'maven:3.6-jdk-11', 'mvn', '-q', 'test'] - print(Docker().execute(command)) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/util/Api.py b/test/util/Api.py deleted file mode 100644 index 64468d83d..000000000 --- a/test/util/Api.py +++ /dev/null @@ -1,9 +0,0 @@ -import requests - -class Api: - def noResponse(self, url): - try: - r = requests.get(url, timeout=5) - except requests.exceptions.ConnectionError: - return True - return False diff --git a/test/util/Docker.py b/test/util/Docker.py deleted file mode 100644 index 7711ba0f7..000000000 --- a/test/util/Docker.py +++ /dev/null @@ -1,39 +0,0 @@ -import re -from subprocess import Popen, PIPE -from random import random - -# From http://blog.bordage.pro/avoid-docker-py/ -class Docker: - def kill_and_remove(self, ctr_name): - command = ['docker', 'rm', '-f', ctr_name] - try: - self.execute(command) - return True - except RuntimeError as e: - print(e) - return False - - def random_container_name(self, prefix): - retstr = prefix + '-' - for i in range(5): - retstr += chr(int(round(random() * (122-97) + 97))) - return retstr - - def get_container_ip(self, ctr_name): - command = ['docker', 'inspect', - '--format', '\'{{.NetworkSettings.IPAddress}}\'', - ctr_name] - return re.sub(r'[^0-9.]*', '', self.execute(command)) - - def execute(self, command, dump_streams=False): - print("Running: " + ' '.join(command)) - p = Popen(command, stdout=PIPE, stderr=PIPE) - out, err = p.communicate() - if dump_streams == True: - print(out.decode('utf-8')) - print(err.decode('utf-8')) - return str(out.decode('utf-8')) - - def start_container(self, container_name="", image="", cmd="", host=""): - command = ['docker', 'run', '-d', '-h', host, '--name', container_name, image] - self.execute(command) diff --git a/test/util/Dredd.py b/test/util/Dredd.py deleted file mode 100644 index fae932e69..000000000 --- a/test/util/Dredd.py +++ /dev/null @@ -1,30 +0,0 @@ -from util.Docker import Docker -from util.Api import Api -import os -import unittest - -class Dredd: - image = 'weaveworksdemos/openapi:snapshot' - container_name = '' - def test_against_endpoint(self, service, api_endpoint, links=[], env=[], dump_streams=False): - self.container_name = Docker().random_container_name('openapi') - command = ['docker', 'run', - '-h', 'openapi', - '--name', self.container_name, - '-v', "{0}:{1}".format(os.getcwd() + "/api-spec/", "/tmp/specs/")] - - if links != []: - [command.extend(["--link", x]) for x in links] - - if env != []: - [command.extend(["--env", "{}={}".format(x[0], x[1])]) for x in env] - - command.extend([Dredd.image, - "/tmp/specs/{0}.json".format(service), - api_endpoint, - "-f", - "/tmp/specs/hooks.js".format(service)]) - out = Docker().execute(command, dump_streams=dump_streams) - - Docker().kill_and_remove(self.container_name) - return out diff --git a/test/util/__init__.py b/test/util/__init__.py deleted file mode 100644 index e69de29bb..000000000