├── .github └── workflows │ └── build.yml ├── .gitignore ├── HOW-TO-RUN.md ├── LICENSE ├── LIESMICH.md ├── README.md ├── WIE-LAUFEN.md ├── docker-vagrant ├── LIESMICH.md ├── README.md ├── Vagrantfile ├── catalog-app │ └── Dockerfile ├── customer-app │ └── Dockerfile ├── eureka │ └── Dockerfile ├── java │ └── Dockerfile ├── order-app │ └── Dockerfile ├── turbine │ └── Dockerfile └── zuul │ └── Dockerfile ├── docker ├── .env ├── LIESMICH.md ├── README.md └── docker-compose.yml ├── microservice-demo ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── microservice-demo-catalog │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── ewolff │ │ │ │ └── microservice │ │ │ │ └── catalog │ │ │ │ ├── CatalogApp.java │ │ │ │ ├── Item.java │ │ │ │ ├── ItemRepository.java │ │ │ │ ├── SpringRestDataConfig.java │ │ │ │ └── web │ │ │ │ └── CatalogController.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── bootstrap.properties │ │ │ └── templates │ │ │ ├── item.html │ │ │ ├── itemlist.html │ │ │ ├── layout.html │ │ │ ├── searchForm.html │ │ │ └── success.html │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── ewolff │ │ │ └── microservice │ │ │ └── catalog │ │ │ ├── CatalogTestApp.java │ │ │ ├── CatalogWebIntegrationTest.java │ │ │ ├── RepositoryTest.java │ │ │ └── cdc │ │ │ ├── CatalogClient.java │ │ │ ├── CatalogConsumerDrivenContractTest.java │ │ │ └── Item.java │ │ └── resources │ │ └── application-test.properties ├── microservice-demo-customer │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── ewolff │ │ │ │ └── microservice │ │ │ │ └── customer │ │ │ │ ├── Customer.java │ │ │ │ ├── CustomerApp.java │ │ │ │ ├── CustomerRepository.java │ │ │ │ ├── SpringRestDataConfig.java │ │ │ │ └── web │ │ │ │ └── CustomerController.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── bootstrap.properties │ │ │ └── templates │ │ │ ├── customer.html │ │ │ ├── customerlist.html │ │ │ ├── layout.html │ │ │ └── success.html │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── ewolff │ │ │ └── microservice │ │ │ └── customer │ │ │ ├── CustomerTestApp.java │ │ │ ├── CustomerWebIntegrationTest.java │ │ │ └── cdc │ │ │ ├── Customer.java │ │ │ ├── CustomerClient.java │ │ │ └── CustomerConsumerDrivenContractTest.java │ │ └── resources │ │ └── application-test.properties ├── microservice-demo-eureka-server │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── ewolff │ │ │ │ └── microservice │ │ │ │ └── eurekaserver │ │ │ │ └── EurekaApplication.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── bootstrap.yml │ │ └── test │ │ └── java │ │ └── com │ │ └── ewolff │ │ └── microservice │ │ └── eurekaserver │ │ └── ApplicationTests.java ├── microservice-demo-order │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── ewolff │ │ │ │ └── microservice │ │ │ │ └── order │ │ │ │ ├── OrderApp.java │ │ │ │ ├── clients │ │ │ │ ├── CatalogClient.java │ │ │ │ ├── Customer.java │ │ │ │ ├── CustomerClient.java │ │ │ │ └── Item.java │ │ │ │ └── logic │ │ │ │ ├── Order.java │ │ │ │ ├── OrderController.java │ │ │ │ ├── OrderLine.java │ │ │ │ ├── OrderRepository.java │ │ │ │ ├── OrderService.java │ │ │ │ └── SpringRestDataConfig.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── bootstrap.properties │ │ │ ├── static │ │ │ └── monitor.html │ │ │ └── templates │ │ │ ├── layout.html │ │ │ ├── order.html │ │ │ ├── orderForm.html │ │ │ ├── orderlist.html │ │ │ └── success.html │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── ewolff │ │ │ └── microservice │ │ │ └── order │ │ │ ├── OrderTestApp.java │ │ │ ├── catalogstub │ │ │ └── CatalogStub.java │ │ │ ├── customerstub │ │ │ └── CustomerStub.java │ │ │ └── logic │ │ │ ├── CatalogConsumerDrivenContractTest.java │ │ │ ├── CustomerConsumerDrivenContractTest.java │ │ │ └── OrderWebIntegrationTest.java │ │ └── resources │ │ └── application-test.properties ├── microservice-demo-turbine-server │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── ewolff │ │ │ └── microservice │ │ │ └── turbine │ │ │ └── TurbineApplication.java │ │ └── resources │ │ ├── application.yml │ │ └── bootstrap.yml ├── microservice-demo-zuul-server │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── ewolff │ │ │ └── microservice │ │ │ └── zuulserver │ │ │ └── ZuulApplication.java │ │ └── resources │ │ ├── application.yml │ │ ├── bootstrap.yml │ │ └── static │ │ └── index.html ├── mvnw ├── mvnw.cmd └── pom.xml └── scripts ├── README.md ├── createdemo.sh └── destroydemo.sh /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish Docker Images 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Set up JDK 10 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: 11 20 | - name: Build microservices with Maven 21 | run: cd microservice-demo && ./mvnw -B package --file pom.xml 22 | - name: Create Docker images 23 | run: cd docker && docker-compose build 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vagrant 3 | .springBeans 4 | .classpath 5 | .project 6 | .settings 7 | target/ 8 | bin/ 9 | pom.xml.tag 10 | pom.xml.releaseBackup 11 | pom.xml.versionsBackup 12 | pom.xml.next 13 | release.properties 14 | dependency-reduced-pom.xml 15 | buildNumber.properties 16 | .mvn/timing.properties 17 | *~ -------------------------------------------------------------------------------- /HOW-TO-RUN.md: -------------------------------------------------------------------------------- 1 | # How to Run 2 | 3 | This is a step-by-step guide how to run the example: 4 | 5 | ## Installation 6 | 7 | * The example is implemented in Java. See 8 | https://www.java.com/en/download/help/download_options.xml . The 9 | examples need to be compiled so you need to install a JDK (Java 10 | Development Kit). A JRE (Java Runtime Environment) is not 11 | sufficient. After the installation you should be able to execute 12 | `java` and `javac` on the command line. 13 | 14 | * The example run in Docker Containers. You need to install Docker 15 | Community Edition, see https://www.docker.com/community-edition/ 16 | . You should be able to run `docker` after the installation. 17 | 18 | * The example need a lot of RAM. You should configure Docker to use 4 19 | GB of RAM. Otherwise Docker containers might be killed due to lack 20 | of RAM. On Windows and macOS you can find the RAM setting in the 21 | Docker application under Preferences/ Advanced. 22 | 23 | * After installing Docker you should also be able to run 24 | `docker-compose`. If this is not possible, you might need to install 25 | it separately. See https://docs.docker.com/compose/install/ . 26 | 27 | ## Build 28 | 29 | Change to the directory `microservice-demo` and run `./mvnw clean 30 | package` or `./mvnw.cmd clean package` (Windows). This will take a while: 31 | 32 | ``` 33 | [~/microservice/microservice-demo]./mvnw clean package 34 | .... 35 | [INFO] 36 | [INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ microservice-demo-zuul-server --- 37 | [INFO] Building jar: /Users/wolff/Desktop/microservice/microservice-demo/microservice-demo-zuul-server/target/microservice-demo-zuul-server-0.0.1-SNAPSHOT.jar 38 | [INFO] 39 | [INFO] --- spring-boot-maven-plugin:1.5.2.RELEASE:repackage (default) @ microservice-demo-zuul-server --- 40 | [INFO] ------------------------------------------------------------------------ 41 | [INFO] Reactor Summary: 42 | [INFO] 43 | [INFO] microservice-demo .................................. SUCCESS [ 1.455 s] 44 | [INFO] microservice-demo-eureka-server .................... SUCCESS [ 16.951 s] 45 | [INFO] microservice-demo-turbine-server ................... SUCCESS [ 0.454 s] 46 | [INFO] microservice-demo-customer ......................... SUCCESS [ 17.268 s] 47 | [INFO] microservice-demo-catalog .......................... SUCCESS [ 19.457 s] 48 | [INFO] microservice-demo-order ............................ SUCCESS [ 18.629 s] 49 | [INFO] microservice-demo-zuul-server ...................... SUCCESS [ 0.266 s] 50 | [INFO] ------------------------------------------------------------------------ 51 | [INFO] BUILD SUCCESS 52 | [INFO] ------------------------------------------------------------------------ 53 | [INFO] Total time: 01:15 min 54 | [INFO] Finished at: 2017-09-07T22:02:55+02:00 55 | [INFO] Final Memory: 62M/429M 56 | [INFO] ------------------------------------------------------------------------ 57 | ``` 58 | 59 | If this does not work: 60 | 61 | * Ensure that `settings.xml` in the directory `.m2` in your home 62 | directory contains no configuration for a specific Maven repo. If in 63 | doubt: delete the file. 64 | 65 | * The tests use some ports on the local machine. Make sure that no 66 | server runs in the background. 67 | 68 | * Skip the tests: `./mvnw clean package 69 | -Dmaven.test.skip=true` or `./mvnw.cmd clean package 70 | -Dmaven.test.skip=true` (Windows). 71 | 72 | * In rare cases dependencies might not be downloaded correctly. In 73 | that case: Remove the directory `repository` in the directory `.m2` 74 | in your home directory. Note that this means all dependencies will 75 | be downloaded again. 76 | 77 | ## Run the containers 78 | 79 | First you need to build the Docker images. Change to the directory 80 | `docker` and run `docker-compose build`. This will download some base 81 | images, install software into Docker images and will therefore take 82 | its time: 83 | 84 | ``` 85 | [~/microservice/docker]docker-compose build 86 | .... 87 | Removing intermediate container 5ed9d5e47a14 88 | Step 4/4 : EXPOSE 8080 89 | ---> Running in ea27ee231d2b 90 | ---> 7f7f51fc9fd4 91 | Removing intermediate container ea27ee231d2b 92 | Successfully built 7f7f51fc9fd4 93 | Successfully tagged ms_order:latest 94 | ``` 95 | 96 | Afterwards the Docker images should have been created. They have the prefix 97 | `ms`: 98 | 99 | ``` 100 | [~/microservice/docker]docker images 101 | REPOSITORY TAG IMAGE ID CREATED SIZE 102 | ms_order latest 7f7f51fc9fd4 50 seconds ago 228MB 103 | ms_turbine latest 8a5cfb2a7b01 54 seconds ago 210MB 104 | ms_catalog latest 395f7bdc04f3 58 seconds ago 228MB 105 | ms_customer latest abeed8b882db About a minute ago 228MB 106 | ms_zuul latest dc240509b408 About a minute ago 210MB 107 | ms_eureka latest 6081c8f9204f About a minute ago 210MB 108 | ``` 109 | 110 | Now you can start the containers using `docker-compose up -d`. The 111 | `-d` option means that the containers will be started in the 112 | background and won't output their stdout to the command line: 113 | 114 | ``` 115 | [~/microservice/docker]docker-compose up -d 116 | Recreating ms_eureka_1 ... 117 | Recreating ms_eureka_1 ... done 118 | Recreating ms_zuul_1 ... 119 | Recreating ms_customer_1 ... 120 | Recreating ms_zuul_1 121 | Recreating ms_order_1 ... 122 | Recreating ms_customer_1 123 | Recreating ms_turbine_1 ... 124 | Creating ms_catalog_1 ... 125 | Recreating ms_order_1 126 | Recreating ms_turbine_1 127 | Recreating ms_customer_1 ... done 128 | ``` 129 | 130 | Check wether all containers are running: 131 | 132 | ``` 133 | [~/microservice/docker]docker ps 134 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 135 | 1f66de9969c0 ms_turbine "/bin/sh -c '/usr/..." 19 seconds ago Up 16 seconds 0.0.0.0:8989->8989/tcp ms_turbine_1 136 | 7fda8c451878 ms_customer "/bin/sh -c '/usr/..." 19 seconds ago Up 15 seconds 8080/tcp ms_customer_1 137 | d26252586c7b ms_order "/bin/sh -c '/usr/..." 19 seconds ago Up 16 seconds 8080/tcp ms_order_1 138 | 26c7f0d59922 ms_zuul "/bin/sh -c '/usr/..." 19 seconds ago Up 17 seconds 0.0.0.0:8080->8080/tcp ms_zuul_1 139 | 45fd39ef1bff ms_catalog "/bin/sh -c '/usr/..." 19 seconds ago Up 17 seconds 8080/tcp ms_catalog_1 140 | 39a1160c11cc ms_eureka "/bin/sh -c '/usr/..." 20 seconds ago Up 19 seconds 0.0.0.0:8761->8761/tcp ms_eureka_1 141 | ``` 142 | `docker ps -a` also shows the terminated Docker containers. That is 143 | useful to see Docker containers that crashed rigth after they started. 144 | 145 | If one of the containers is not running, you can look at its logs using 146 | e.g. `docker logs ms_order_1`. The name of the container is 147 | given in the last column of the output of `docker ps`. Looking at the 148 | logs even works after the container has been 149 | terminated. If the log says that the container has been `killed`, you 150 | need to increase the RAM assigned to Docker to e.g. 4GB. On Windows 151 | and macOS you can find the RAM setting in the Docker application under 152 | Preferences/ Advanced. 153 | 154 | If you need to do more trouble shooting open a shell in the container 155 | using e.g. `docker exec -it ms_catalog_1 /bin/sh` or execute 156 | command using `docker exec ms_catalog_1 /bin/ls`. 157 | 158 | You can access: 159 | 160 | * The application through Zuul at http://localhost:8080/ 161 | * The Eureka dashboard at http://localhost:8761/ 162 | * The Hystrix dashboard at http://localhost:8989/ 163 | 164 | You can terminate all containers using `docker-compose down`. 165 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /LIESMICH.md: -------------------------------------------------------------------------------- 1 | Microservice Demo 2 | ============= 3 | 4 | Dieses Projekt ist eine Demo für das 5 | [Microservices Buch](http://microservices-buch.de/) ([English](http://microservices-book.com/)). 6 | 7 | Dieses Projekt erzeugt eine vollständigen Microservice-Demo in 8 | Docker-Containern. Die Services sind mit Java, Spring und Spring Cloud 9 | implementiert. 10 | 11 | Das System hat drei Microservices: 12 | - Order um Bestellungen entgegenzunehmen 13 | - Customer für Kundendaten 14 | - Catalog für die Waren 15 | 16 | Technologien 17 | ------------ 18 | 19 | - Eureka für Service Discovery 20 | - Ribbon für Load Balancing. Siehe die Klassen CatalogClient und 21 | CustomerClient in com.ewolff.microservice.order.clients im Projekt 22 | microservice-demo-order . 23 | - Hystrix für Resilience. Siehe CatalogClient in 24 | com.ewolff.microservice.order.clients im microservice-demo-order 25 | Projekt . Der CustomerClient nutzt Hystrix nicht. So ist 26 | nachvollziehbar, welche Probleme der crash des Customer microservice 27 | verursacht - der Order microservice wird praktisch unbrauchbar. 28 | - Hystrix hat ein Dashboard. Turbine kann genutzt werden, um die 29 | Hystrix-Daten aus mehreren Quellen zu kombinieren. Allerdings 30 | funktioniert das noch nicht. 31 | - Zuul wird dazu genutzt, um HTTP-Requests von außen auf die 32 | verschiedenen Dienste zu verteilen. 33 | - Spring Cloud Config wurde nicht genutzt - daher 34 | spring.cloud.config.enabled=false in den Bootstrap-Files. 35 | 36 | 37 | Ausführen 38 | --------- 39 | 40 | Das Beispiel kann entweder mit [Vagrant](docker-vagrant/LIESMICH.md) betrieben werden - oder mit [Docker Machine und Docker 41 | Compose](docker/LIESMICH.md). Details finden sich in [Wie laufen](WIE-LAUFEN.md). 42 | 43 | Hinweise zum Code 44 | ----------------- 45 | 46 | Die Server für die Infrastruktur sind recht einfach - dank Spring Cloud: 47 | 48 | - microservice-demo-eureka ist der Eureka-Server für Service Discovery. 49 | - microservice-demo-zuul implementiert den Zuul-Server. Er verteilt die eingehenden Anfragen auf die drei Microservices. 50 | - microservice-demo-turbine kann zum Konsolidieren der Hystrix-Metriken genutzt werden und bietet auerdem ein Hystrix-Dashboard an. 51 | 52 | Die microservices sind: 53 | - microservice-demo-catalog verwaltet die verschiedenen Waren. 54 | - microserivce-demo-customer ist für die Kunden zuständig 55 | - microservice-demo-order implementiert die Bearbeitung der Bestellungen. Der Microservice nutzt microservice-demo-catalog und microservice-demo-customer. Der Service nutzt Ribbon für Load Balancing und Hystrix für Resilience. 56 | 57 | Die Microservices haben ein Java-Hauptprogramm im src/test/java, um die Services einzeln zu betreiben - also ohne Eureka oder die anderen Services. Dann werden die anderen Services durch Stubs simuliert. Außerdem gibt es Tests, die Customer Driven Contract verwenden. Damit wird sichergestellt, dass die anderen Services die Schnittstellen korrekt implementieren. Außerdem werden die CDC-Tests in microserice-demo-order genutzt, um die Stubs zu überprüfen. In microserivce-demo-customer und microserivce-demo-catalog werden sie genutzt, um die korrekte Implementierung der REST-Services abzusichern. 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Microservice Sample 2 | ============== 3 | 4 |
5 | Translations: 6 | 7 | - [German / Deutsch](LIESMICH.md) 8 | 9 |
10 | 11 | This is a sample for my 12 | Microservices Book ([English](http://microservices-book.com/) / [German](http://microservices-buch.de/)). 13 | 14 | This project creates a VM with the complete micro service demo system 15 | in Docker containers inside a Vagrant VM. The services are implemented 16 | in Java using Spring and Spring Cloud. 17 | 18 | It uses three microservices: 19 | - Order to process orders. 20 | - Customer to handle customer data. 21 | - Catalog to handle the items in the catalog. 22 | 23 | Technologies 24 | ------------ 25 | 26 | - Eureka for Lookup 27 | - Ribbon for Load Balancing. See the classes CatalogClient and 28 | CustomerClient in com.ewolff.microservice.order.clients in the 29 | microservice-demo-order project. 30 | - Hystrix is used for resilience. See CatalogClient in 31 | com.ewolff.microservice.order.clients in the microservice-demo-order 32 | project . Note that the CustomerClient won't use Hystrix. This way 33 | you can see how a crash of the Customer microservices makes the 34 | Order microservice useless. 35 | - Hystrix has a dashboard. Turbine can be used to combine the data 36 | from multiple sources. However, this does not work at the moment. 37 | - Zuul is used to route HTTP requests from the outside to the 38 | different services. 39 | - Spring Cloud Config isn't used. It is disabled with 40 | spring.cloud.config.enabled=false in the bootstrap files. 41 | 42 | 43 | How To Run 44 | ---------- 45 | 46 | The demo can be run with [Vagrant](docker-vagrant/README.md) or [Docker Machine and Docker 47 | Compose](docker/README.md). 48 | 49 | [How to run](HOW-TO-RUN.md) includes more details. 50 | 51 |
52 | Translations: 53 | 54 | - [German / Deutsch](WIE-LAUFEN.md) 55 | 56 |
57 | 58 | 59 | Remarks on the Code 60 | ------------------- 61 | 62 | The servers for the infrastructure are pretty simple thanks to Spring Cloud: 63 | 64 | - microservice-demo-eureka is the Eureka server for service discovery. 65 | - microservice-demo-zuul is the Zuul server. It distributes the requests to the three microservices. 66 | - microservice-demo-turbine can be used to consolidate the Hystrix metrics and has a Hystrix dashboard. 67 | 68 | The microservices are: 69 | - microservice-demo-catalog is the application to take care of items. 70 | - microserivce-demo-customer is responsible for customers. 71 | - microservice-demo-order does order processing. It uses microservice-demo-catalog and microservice-demo-customer. Ribbon is used for load balancing and Hystrix for resilience. 72 | 73 | 74 | The microservices have a Java main application in src/test/java to run them stand alone. microservice-demo-order uses a stub for the other services then. Also, there are tests that use customer driven contracts. That is why it is ensured that the services provide the correct interface. These CDC tests are used in microservice-demo-order to verify the stubs. In microserivce-demo-customer and microserivce-demo-catalog they are used to verify the implemented REST services. 75 | -------------------------------------------------------------------------------- /WIE-LAUFEN.md: -------------------------------------------------------------------------------- 1 | # Beispiel starten 2 | 3 | Die ist eine Schritt-für-Schritt-Anleitung zum Starten der Beispiele. 4 | Informationen zu Maven und Docker finden sich im 5 | [Cheatsheet-Projekt](https://github.com/ewolff/cheatsheets-DE). 6 | 7 | ## Installation 8 | 9 | * Die Beispiele sind in Java implementiert. Daher muss Java 10 | installiert werden. Die Anleitung findet sich unter 11 | https://www.java.com/en/download/help/download_options.xml . Da die 12 | Beispiele kompiliert werden müssen, muss ein JDK (Java Development 13 | Kit) installiert werden. Das JRE (Java Runtime Environment) reicht 14 | nicht aus. Nach der Installation sollte sowohl `java` und `javac` in 15 | der Eingabeaufforderung möglich sein. 16 | 17 | * Die Beispiele laufen in Docker Containern. Dazu ist eine 18 | Installation von Docker Community Edition notwendig, siehe 19 | https://www.docker.com/community-edition/ . Docker kann mit 20 | `docker` aufgerufen werden. Das sollte nach der Installation ohne 21 | Fehler möglich sein. 22 | 23 | * Die Beispiele benötigen zum Teil sehr viel Speicher. Daher sollte 24 | Docker ca. 4 GB zur Verfügung haben. Sonst kann es vorkommen, dass 25 | Docker Container aus Speichermangel beendet werden. Unter Windows 26 | und macOS findet sich die Einstellung dafür in der Docker-Anwendung 27 | unter Preferences/ Advanced. 28 | 29 | * Nach der Installation von Docker sollte `docker-compose` aufrufbar 30 | sein. Wenn Docker Compose nicht aufgerufen werden kann, ist es nicht 31 | als Teil der Docker Community Edition installiert worden. Dann ist 32 | eine separate Installation notwendig, siehe 33 | https://docs.docker.com/compose/install/ . 34 | 35 | ## Build 36 | 37 | Wechsel in das Verzeichnis `microservice-demo` und starte `./mvnw clean 38 | package` bzw. `mvnw.cmd clean package` (Windows). Das wird einige Zeit dauern: 39 | 40 | ``` 41 | [~/microservice/microservice-demo]./mvnw clean package 42 | .... 43 | [INFO] 44 | [INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ microservice-demo-zuul-server --- 45 | [INFO] Building jar: /Users/wolff/Desktop/microservice/microservice-demo/microservice-demo-zuul-server/target/microservice-demo-zuul-server-0.0.1-SNAPSHOT.jar 46 | [INFO] 47 | [INFO] --- spring-boot-maven-plugin:1.5.2.RELEASE:repackage (default) @ microservice-demo-zuul-server --- 48 | [INFO] ------------------------------------------------------------------------ 49 | [INFO] Reactor Summary: 50 | [INFO] 51 | [INFO] microservice-demo .................................. SUCCESS [ 1.455 s] 52 | [INFO] microservice-demo-eureka-server .................... SUCCESS [ 16.951 s] 53 | [INFO] microservice-demo-turbine-server ................... SUCCESS [ 0.454 s] 54 | [INFO] microservice-demo-customer ......................... SUCCESS [ 17.268 s] 55 | [INFO] microservice-demo-catalog .......................... SUCCESS [ 19.457 s] 56 | [INFO] microservice-demo-order ............................ SUCCESS [ 18.629 s] 57 | [INFO] microservice-demo-zuul-server ...................... SUCCESS [ 0.266 s] 58 | [INFO] ------------------------------------------------------------------------ 59 | [INFO] BUILD SUCCESS 60 | [INFO] ------------------------------------------------------------------------ 61 | [INFO] Total time: 01:15 min 62 | [INFO] Finished at: 2017-09-07T22:02:55+02:00 63 | [INFO] Final Memory: 62M/429M 64 | [INFO] ------------------------------------------------------------------------ 65 | ``` 66 | 67 | Weitere Information zu Maven gibt es im 68 | [Maven Cheatsheet](https://github.com/ewolff/cheatsheets-DE/blob/master/MavenCheatSheet.md). 69 | 70 | Falls es dabei zu Fehlern kommt: 71 | 72 | * Stelle sicher, dass die Datei `settings.xml` im Verzeichnis `.m2` 73 | in deinem Heimatverzeichnis keine Konfiguration für ein spezielles 74 | Maven Repository enthalten. Im Zweifelsfall kannst du die Datei 75 | einfach löschen. 76 | 77 | * Die Tests nutzen einige Ports auf dem Rechner. Stelle sicher, dass 78 | im Hintergrund keine Server laufen. 79 | 80 | * Führe die Tests beim Build nicht aus: `./mvnw clean package 81 | -Dmaven.test.skip=true` bzw. `mvnw.cmd clean package 82 | -Dmaven.test.skip=true`. 83 | 84 | * In einigen selten Fällen kann es vorkommen, dass die Abhängigkeiten 85 | nicht korrekt heruntergeladen werden. Wenn du das Verzeichnis 86 | `repository` im Verzeichnis `.m2` löscht, werden alle Abhängigkeiten 87 | erneut heruntergeladen. 88 | 89 | ## Docker Container starten 90 | 91 | Weitere Information zu Docker gibt es im 92 | [Docker Cheatsheet](https://github.com/ewolff/cheatsheets-DE/blob/master/DockerCheatSheet.md). 93 | 94 | Zunächst musst du die Docker Images bauen. Wechsel in das Verzeichnis 95 | `docker` und starte `docker-compose build`. Das lädt die Basis-Images 96 | herunter und installiert die Software in die Docker Images: 97 | 98 | ``` 99 | [~/microservice/docker]docker-compose build 100 | .... 101 | Removing intermediate container 5ed9d5e47a14 102 | Step 4/4 : EXPOSE 8080 103 | ---> Running in ea27ee231d2b 104 | ---> 7f7f51fc9fd4 105 | Removing intermediate container ea27ee231d2b 106 | Successfully built 7f7f51fc9fd4 107 | Successfully tagged ms_order:latest 108 | ``` 109 | 110 | Danach sollten die Docker Images erzeugt worden sein. Sie haben das 111 | Präfix `ms`: 112 | 113 | ``` 114 | [~/microservice/docker]docker images 115 | REPOSITORY TAG IMAGE ID CREATED SIZE 116 | ms_order latest 7f7f51fc9fd4 50 seconds ago 228MB 117 | ms_turbine latest 8a5cfb2a7b01 54 seconds ago 210MB 118 | ms_catalog latest 395f7bdc04f3 58 seconds ago 228MB 119 | ms_customer latest abeed8b882db About a minute ago 228MB 120 | ms_zuul latest dc240509b408 About a minute ago 210MB 121 | ms_eureka latest 6081c8f9204f About a minute ago 210MB 122 | ``` 123 | 124 | Nun kannst Du die Container mit `docker-compose up -d` starten. Die 125 | Option `-d` bedeutet, dass die Container im Hintergrund gestartet 126 | werden und keine Ausgabe auf der Kommandozeile erzeugen. 127 | 128 | ``` 129 | [~/microservice/docker]docker-compose up -d 130 | Recreating ms_eureka_1 ... 131 | Recreating ms_eureka_1 ... done 132 | Recreating ms_zuul_1 ... 133 | Recreating ms_customer_1 ... 134 | Recreating ms_zuul_1 135 | Recreating ms_order_1 ... 136 | Recreating ms_customer_1 137 | Recreating ms_turbine_1 ... 138 | Creating ms_catalog_1 ... 139 | Recreating ms_order_1 140 | Recreating ms_turbine_1 141 | Recreating ms_customer_1 ... done 142 | ``` 143 | 144 | Du kannst nun überprüfen, ob alle Docker Container laufen: 145 | 146 | ``` 147 | [~/microservice/docker]docker ps 148 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 149 | 1f66de9969c0 ms_turbine "/bin/sh -c '/usr/..." 19 seconds ago Up 16 seconds 0.0.0.0:8989->8989/tcp ms_turbine_1 150 | 7fda8c451878 ms_customer "/bin/sh -c '/usr/..." 19 seconds ago Up 15 seconds 8080/tcp ms_customer_1 151 | d26252586c7b ms_order "/bin/sh -c '/usr/..." 19 seconds ago Up 16 seconds 8080/tcp ms_order_1 152 | 26c7f0d59922 ms_zuul "/bin/sh -c '/usr/..." 19 seconds ago Up 17 seconds 0.0.0.0:8080->8080/tcp ms_zuul_1 153 | 45fd39ef1bff ms_catalog "/bin/sh -c '/usr/..." 19 seconds ago Up 17 seconds 8080/tcp ms_catalog_1 154 | 39a1160c11cc ms_eureka "/bin/sh -c '/usr/..." 20 seconds ago Up 19 seconds 0.0.0.0:8761->8761/tcp ms_eureka_1 155 | ``` 156 | 157 | `docker ps -a` zeigt auch die terminierten Docker Container an. Das 158 | ist nützlich, wenn ein Docker Container sich sofort nach dem Start 159 | wieder beendet.. 160 | 161 | Wenn einer der Docker Container nicht läuft, kannst du dir die Logs 162 | beispielsweise mit `docker logs ms_apache_1` anschauen. Der Name 163 | der Container steht in der letzten Spalte der Ausgabe von `docker 164 | ps`. Das Anzeigen der Logs funktioniert auch dann, wenn der Container 165 | bereits beendet worden ist. Falls im Log steht, dass der Container 166 | `killed` ist, dann hat Docker den Container wegen Speichermangel 167 | beendet. Du solltest Docker mehr RAM zuweisen z.B. 4GB. Unter Windows 168 | und macOS findet sich die RAM-Einstellung in der Docker application 169 | unter Preferences/ Advanced. 170 | 171 | Um einen Container genauer zu untersuchen, kannst du eine Shell in dem 172 | Container starten. Beispielsweise mit `docker exec -it 173 | ms_catalog_1 /bin/sh` oder du kannst in dem Container ein 174 | Kommando mit `docker exec ms_catalog_1 /bin/ls` ausführen. 175 | 176 | Es stehen nun bereit: 177 | 178 | * Die Anwendung selber durch Zuul unter http://localhost:8080/ 179 | * Das Eureka Dashboard unter http://localhost:8761/ 180 | * Das Hystrix Dashboard unter http://localhost:8989/ 181 | 182 | Mit `docker-compose down` kannst Du alle Container beenden. 183 | 184 | -------------------------------------------------------------------------------- /docker-vagrant/LIESMICH.md: -------------------------------------------------------------------------------- 1 | Microservice Demo mit Vagrant betreiben 2 | ============================ 3 | 4 | Vagrant kann virtuelle Machine erstellen, auf denen dann Software 5 | installiert werden kann. In diesem Beispiel wird in der virtuellen 6 | Maschine Docker installiert und anschließend die Docker Container deployt. 7 | 8 | Um das Beispiel ablaufen zu lassen: 9 | 10 | - Installiere Maven, siehe https://maven.apache.org/download.cgi 11 | - Installiere Vagrant, siehe 12 | http://docs.vagrantup.com/v2/installation/index.html 13 | - Installiere Virtual Box von https://www.virtualbox.org/wiki/Downloads 14 | - Gehe zum Verzeichnis `microservice-demo` und führe dort `mvn package` aus 15 | - Wechsel zum Verzeichnis `docker-vagrant` und führe `vagrant 16 | up` aus. Beim jedem Start der Vagrant VM werden die Docker Container mitgestartet. 17 | - Mit `vagrant halt` kann die Vagrnat VM beendet werden. `vagrant destroy` löscht 18 | alle Dateien der VM. Mit `vagrant ssh` kann man sich in die VM einloggen und mit 19 | `vagrant provision` die Provisionierung erneut starten. Dann werden die Docker container 20 | neu gebaut. 21 | 22 | Das Ergebnis: 23 | 24 | - Eine VirtualBox VM wird von Vagrant gestartet 25 | - Docker wird in der VM gestartet 26 | - Die Anwendung steht unter http://127.0.0.1:18080/ zur 27 | Verfügung. Dort gibt es auch eine Seite mit Links zu den anderen 28 | Diensten. 29 | - Das Eureka-Dashboard steht unter http://127.0.0.1:18761/ zur Verfügung. 30 | - Das Hystrix-Dashboard steht unter http://127.0.0.1:18080/turbine/hystrix zur 31 | Verfügung. Die URL für einen einzelnen Order-Server dort lautet 32 | http://172.17.0.9:8080/hystrix.stream - wobei die IP-Adresse sich 33 | ändert. Sie kann im Eureka-Dashboard für den Dienst order-app 34 | ermittelt werden. Die Alternative ist der Turbine Stream des Order 35 | Services. Er enthält die Daten aller Order-Servives. Dazu muss die Adresse 36 | http://172.17.0.10:8989/turbine.stream?cluster=ORDER der Order App genutzt werden - 37 | wobei die IP-Adresse des Turbine Service sich aus dem Eureka Dashboard 38 | entnehmen lässt. 39 | 40 | Die folgenden Port werden auf `localhost` genutzt: 41 | 42 | - 18080 für die Web-Anwendung 43 | - 18761 für Eureka 44 | - 18989 für den Turbine-Server 45 | 46 | -------------------------------------------------------------------------------- /docker-vagrant/README.md: -------------------------------------------------------------------------------- 1 | Run Microservices Demo with Vagrant 2 | ========================== 3 | 4 | Vagrant can set up virtual machines to install software on them. In 5 | this example Vagrant install Docker on the virtual machine and deploys 6 | Docker Containers afterwards. 7 | 8 | To run the demo: 9 | 10 | - Install Maven, see https://maven.apache.org/download.cgi 11 | - Install Virtual Box from https://www.virtualbox.org/wiki/Downloads 12 | - Install Vagrant as discussed at 13 | http://docs.vagrantup.com/v2/installation/index.html 14 | - Go to directory `microservice-demo` and run `mvn package` there 15 | - Change to the directory `docker-vagrant` and run `vagrant 16 | up`. Each time you start the Vagrant VM the Docker containers will be started, too. 17 | 18 | The result should be: 19 | 20 | - A new VirtualBox VM is fired up by Vagrant 21 | - Docker is installed in the VM 22 | - You can access the application at http://127.0.0.1:18080/ . It has a 23 | web page with links to all other services. 24 | - You can access the Eureka dashboard at http://127.0.0.1:18761/ 25 | - You can access the Turbine dashboard at 26 | http://127.0.0.1:18080/turbine/hystrix . The URL for the data stream of all 27 | Hystrix data of all Order nodes is 28 | http://172.17.0.10:8989/turbine.stream?cluster=ORDER - the IP-Adresse 29 | changes. Look it up in the Eureka dashboard for service turbine. You 30 | can also connect to a Hystrix stream of an order service. You need to 31 | use the address http://172.17.0.9:8080/hystrix.stream of the Order 32 | App. The IP address can be found in the Eureka dashboard. 33 | 34 | Additonal hints: 35 | 36 | - Use `vagrant halt` to shut down the system or `vagrant destroy` to 37 | to delete the VM. 38 | - If you wantt login to the VM, please use `vagrant ssh`. 39 | - If you update the code, you need to rebuild it and then do a new 40 | provisioning using `vagrant provision` . Then the Docker containers in the Vagrant VM will be rebuild. 41 | 42 | The following ports will be used on `localhost` : 43 | 44 | - 18080 for the web application 45 | - 18761 for Eureka 46 | - 18989 for the Turbine server 47 | -------------------------------------------------------------------------------- /docker-vagrant/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.box = "ubuntu/bionic64" 3 | config.vm.synced_folder "../microservice-demo", "/microservice-demo", create: true 4 | config.vm.network "forwarded_port", guest: 8080, host: 18080 5 | config.vm.network "forwarded_port", guest: 8761, host: 18761 6 | config.vm.network "forwarded_port", guest: 8989, host: 18989 7 | config.vm.provider "virtualbox" do |v| 8 | v.memory = 3000 9 | v.cpus = 2 10 | end 11 | 12 | config.vm.provision "docker" do |d| 13 | d.build_image "--tag=java /vagrant/java" 14 | d.build_image "--tag=eureka /vagrant/eureka" 15 | d.build_image "--tag=customer-app /vagrant/customer-app" 16 | d.build_image "--tag=catalog-app /vagrant/catalog-app" 17 | d.build_image "--tag=order-app /vagrant/order-app" 18 | d.build_image "--tag=turbine /vagrant/turbine" 19 | d.build_image "--tag=zuul /vagrant/zuul" 20 | end 21 | config.vm.provision "docker", run: "always" do |d| 22 | d.run "eureka", 23 | args: "-p 8761:8761 -v /microservice-demo:/microservice-demo" 24 | d.run "customer-app", 25 | args: "-v /microservice-demo:/microservice-demo --link eureka:eureka" 26 | d.run "catalog-app", 27 | args: "-v /microservice-demo:/microservice-demo --link eureka:eureka" 28 | d.run "order-app", 29 | args: "-v /microservice-demo:/microservice-demo --link eureka:eureka" 30 | d.run "zuul", 31 | args: "-p 8080:8080 -v /microservice-demo:/microservice-demo --link eureka:eureka" 32 | d.run "turbine", 33 | args: "-p 8989:8989 -v /microservice-demo:/microservice-demo --link eureka:eureka" 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /docker-vagrant/catalog-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java 2 | CMD /usr/bin/java -Xmx400m -Xms400m -jar /microservice-demo/microservice-demo-catalog/target/microservice-demo-catalog-0.0.1-SNAPSHOT.jar 3 | EXPOSE 8080 -------------------------------------------------------------------------------- /docker-vagrant/customer-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java 2 | CMD /usr/bin/java -Xmx400m -Xms400m -jar /microservice-demo/microservice-demo-customer/target/microservice-demo-customer-0.0.1-SNAPSHOT.jar 3 | EXPOSE 8080 -------------------------------------------------------------------------------- /docker-vagrant/eureka/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java 2 | CMD /usr/bin/java -Xmx400m -Xms400m -jar /microservice-demo/microservice-demo-eureka-server/target/microservice-demo-eureka-server-0.0.1-SNAPSHOT.jar 3 | EXPOSE 8761 -------------------------------------------------------------------------------- /docker-vagrant/java/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:10.0.2-jre-slim -------------------------------------------------------------------------------- /docker-vagrant/order-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java 2 | CMD /usr/bin/java -Xmx400m -Xms400m -jar /microservice-demo/microservice-demo-order/target/microservice-demo-order-0.0.1-SNAPSHOT.jar 3 | EXPOSE 8080 -------------------------------------------------------------------------------- /docker-vagrant/turbine/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java 2 | CMD /usr/bin/java -Xmx400m -Xms400m -jar /microservice-demo/microservice-demo-turbine-server/target/microservice-demo-turbine-server-0.0.1-SNAPSHOT.jar 3 | EXPOSE 8989 -------------------------------------------------------------------------------- /docker-vagrant/zuul/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java 2 | CMD /usr/bin/java -Xmx400m -Xms400m -jar /microservice-demo/microservice-demo-zuul-server/target/microservice-demo-zuul-server-0.0.1-SNAPSHOT.jar 3 | EXPOSE 8080 -------------------------------------------------------------------------------- /docker/.env: -------------------------------------------------------------------------------- 1 | COMPOSE_PROJECT_NAME=ms -------------------------------------------------------------------------------- /docker/LIESMICH.md: -------------------------------------------------------------------------------- 1 | Microservice Demo mit Docker Machine und Dokcer 2 | ============================ 3 | 4 | Docker Machine kann virtuelle Machine erstellen, auf denen dann Docker 5 | Container laufen können. 6 | 7 | Um das Beispiel ablaufen zu lassen: 8 | 9 | - Installiere Docker Compose, siehe 10 | https://docs.docker.com/compose/#installation-and-set-up 11 | - Optional: Installiere Docker Machine, siehe 12 | https://docs.docker.com/machine/#installation 13 | - Install Docker, see https://docs.docker.com/installation/ 14 | - Installiere Virtual Box von https://www.virtualbox.org/wiki/Downloads 15 | - Gehe zum Verzeichnis `microservice-demo` und führe dort `mvn package` aus 16 | - Optional: Um die Demo mit Docker Machine zu starten: 17 | - Führe `docker-machine create --virtualbox-memory "4096" --driver 18 | virtualbox dev` aus. Das erzeugt eine neue Umgebung names`dev`mit Docker 19 | Machine. Es wird eine virtuelle Machine in Virtual Box mit 4GB RAM sein. 20 | - Führe `eval "$(docker-machine env dev)"` (Linux / Mac OS X) aus. Es 21 | kann notwendig sein, die Shell anzugeben: 22 | `eval "$(docker-machine env --shell bash dev)"`. Für Windows 23 | ist das Commando 24 | `docker-machine.exe env --shell powershell dev` (Windows, 25 | Powershell) / `docker-machine.exe env --shell cmd dev` (Windows, 26 | cmd.exe). Das docker Kommando nutzt nun die neue virtuelle Maschine als Umgebung. 27 | - Führe im Verzeichnis `docker` das Kommando `docker-compose 28 | build` aus und dann `docker-compose up -d`. 29 | 30 | Das Ergebnis: 31 | 32 | - Docker Compose erzeugt die Docker Images und startet sie. 33 | - Eine VirtualBox VM wird von Vagrant gestartet 34 | - Docker wird in der VM gestartet 35 | - Die Anwendung steht unter http://localhost:8080/ zur 36 | Verfügung. Dort gibt es auch eine Seite mit Links zu den anderen 37 | Diensten. 38 | - Das Eureka-Dashboard steht unter http://localhost:8761/ zur Verfügung. 39 | - Das Hystrix-Dashboard steht unter http://localhost:8989/hystrix zur 40 | Verfügung. 41 | - Die URL für einen einzelnen Order-Server lautet 42 | http://172.17.0.9:8080/hystrix.stream - wobei die IP-Adresse sich 43 | ändert. Sie kann im Eureka-Dashboard für den Dienst ORDER 44 | ermittelt werden. 45 | - Die Alternative ist der Turbine Stream des Order 46 | Services. Er enthält die Daten aller Order-Service-Instanzen. Dazu muss die URL 47 | http://172.17.0.10:8989/turbine.stream?cluster=ORDER genutzt 48 | werden. Die IP-Adresse des Turbine Service lässt sich aus dem Eureka Dashboard 49 | entnehmen. `ORDER` definiert, dass der Order-Service dargestellt 50 | werden soll. 51 | 52 | Bei der Nutzung von Docker Machine: 53 | 54 | - Finde mit `docker-machine ip dev`die IP-Adresse der virtuellen Maschine. Nutze diese IP-Adresse anstelle von `localhost` in den URLs oben. 55 | - Nutze `docker-machine rm dev`, um die virtuelle Maschine wieder zu zerstören. 56 | 57 | 58 | Die folgenden Port werden auf dem Docker Host genutzt: 59 | 60 | - 8080 für die Web-Anwendung 61 | - 8761 für Eureka 62 | - 8989 für den Turbine-Server 63 | 64 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | Run Microservices Demo with Docker Compose and Docker Machine 2 | ============================================== 3 | 4 | Docker Machine can create virtual machines to run Docker on. It 5 | supports Virtual Box but also many other technologies including 6 | several clouds. Docker Compose create all the Docker containers needed 7 | fot the systems. 8 | 9 | To run the demo: 10 | 11 | - Install Maven, see https://maven.apache.org/download.cgi 12 | - Install Virtual Box from https://www.virtualbox.org/wiki/Downloads 13 | - Install Docker Compose, see 14 | https://docs.docker.com/compose/#installation-and-set-up 15 | - Install Docker, see https://docs.docker.com/installation/ 16 | - Install Docker Machine, see https://docs.docker.com/machine/#installation (optional) 17 | - Go to directory `microservice-demo` and run `mvn package` there 18 | - If you want to use Docker Machine to run the demo on a different host (optional): 19 | - Execute `docker-machine create --virtualbox-memory "4096" --driver 20 | virtualbox dev` . This will create a new environment called `dev`with Docker 21 | Machine. It will be virtual machine in Virtual Box with 4GB RAM. 22 | - Execute `eval "$(docker-machine env dev)"` (Linux / Mac OS X). You 23 | might need to set your shell: `eval "$(docker-machine env --shell 24 | bash dev)"`. For Windows it's 25 | `docker-machine.exe env --shell powershell dev` (Windows, 26 | Powershell) / `docker-machine.exe env --shell cmd dev` (Windows, 27 | cmd.exe). Now the docker tool will use the newly created virtual 28 | machine as environment. 29 | - Change to the directory `docker` and run `docker-compose 30 | build`followed by `docker-compose up -d`. 31 | 32 | 33 | The result should be: 34 | 35 | - Docker Compose builds the Docker images and runs them. 36 | - You can access the application at http://localhost:8080/ . It has a 37 | web page with links to all other services. 38 | - You can find the Eureka dashboard at http://localhost:8761/. 39 | - The Hystrix dashboard can be found at http://localhost:8989/hystrix . 40 | - You can access the Turbine dashboard by follwing the link on the 41 | page. 42 | - You need to use the address http://172.17.0.9:8080/hystrix.stream 43 | of the Order App. The IP address can be found in the Eureka dashboard. 44 | - The URL for the data stream of all Hystrix data of all Order 45 | nodes is http://172.17.0.10:8989/turbine.stream?cluster=ORDER - the 46 | IP-Adresse changes. Look up the IP adress in the Eureka dashboard for service 47 | TURBINE. 48 | 49 | If you are using Docker Machine: 50 | - Use `docker-machine ip dev` to find the IP adress of the virtual machine. Use this instead of `localhost` in the URLs above. 51 | - Use `docker-machine rm dev` to destroy the virtual machine. 52 | 53 | 54 | The following ports will be used on the Docker host or your local machine: 55 | 56 | - 8080 for the web application 57 | - 8761 for Eureka 58 | - 8989 for the Turbine server 59 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | eureka: 4 | build: ../microservice-demo/microservice-demo-eureka-server 5 | ports: 6 | - "8761:8761" 7 | customer: 8 | build: ../microservice-demo/microservice-demo-customer 9 | links: 10 | - eureka 11 | catalog: 12 | build: ../microservice-demo/microservice-demo-catalog 13 | links: 14 | - eureka 15 | order: 16 | build: ../microservice-demo/microservice-demo-order 17 | links: 18 | - eureka 19 | zuul: 20 | build: ../microservice-demo/microservice-demo-zuul-server 21 | links: 22 | - eureka 23 | ports: 24 | - "8080:8080" 25 | turbine: 26 | build: ../microservice-demo/microservice-demo-turbine-server 27 | links: 28 | - eureka 29 | ports: 30 | - "8989:8989" 31 | 32 | 33 | -------------------------------------------------------------------------------- /microservice-demo/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ewolff/microservice/d1ccf504df5617288479902ad9eb2111df73ed65/microservice-demo/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /microservice-demo/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:11.0.2-jre-slim 2 | COPY target/microservice-demo-catalog-0.0.1-SNAPSHOT.jar . 3 | CMD /usr/bin/java -Xmx400m -Xms400m -jar microservice-demo-catalog-0.0.1-SNAPSHOT.jar 4 | EXPOSE 8080 5 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.ewolff 7 | microservice-demo 8 | 0.0.1-SNAPSHOT 9 | 10 | 11 | microservice-demo-catalog 12 | 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-client 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-jpa 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-data-rest 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-thymeleaf 33 | 34 | 35 | 36 | nz.net.ultraq.thymeleaf 37 | thymeleaf-layout-dialect 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-web 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-actuator 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | 57 | org.springframework.hateoas 58 | spring-hateoas 59 | 60 | 61 | 62 | javax.xml.bind 63 | jaxb-api 64 | 65 | 66 | 67 | com.jayway.jsonpath 68 | json-path 69 | runtime 70 | 71 | 72 | 73 | org.hsqldb 74 | hsqldb 75 | runtime 76 | 77 | 78 | 79 | commons-lang 80 | commons-lang 81 | 2.6 82 | 83 | 84 | 85 | org.webjars 86 | bootstrap 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/java/com/ewolff/microservice/catalog/CatalogApp.java: -------------------------------------------------------------------------------- 1 | package com.ewolff.microservice.catalog; 2 | 3 | import javax.annotation.PostConstruct; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 8 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 9 | import org.springframework.context.annotation.ComponentScan; 10 | import org.springframework.stereotype.Component; 11 | 12 | @ComponentScan 13 | @EnableAutoConfiguration 14 | @EnableDiscoveryClient 15 | @Component 16 | public class CatalogApp { 17 | 18 | private final ItemRepository itemRepository; 19 | 20 | @Autowired 21 | public CatalogApp(ItemRepository itemRepository) { 22 | this.itemRepository = itemRepository; 23 | } 24 | 25 | @PostConstruct 26 | public void generateTestData() { 27 | itemRepository.save(new Item("iPod", 42.0)); 28 | itemRepository.save(new Item("iPod touch", 21.0)); 29 | itemRepository.save(new Item("iPod nano", 1.0)); 30 | itemRepository.save(new Item("Apple TV", 100.0)); 31 | } 32 | 33 | public static void main(String[] args) { 34 | SpringApplication.run(CatalogApp.class, args); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/java/com/ewolff/microservice/catalog/Item.java: -------------------------------------------------------------------------------- 1 | package com.ewolff.microservice.catalog; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.Id; 7 | 8 | import org.apache.commons.lang.builder.EqualsBuilder; 9 | import org.apache.commons.lang.builder.HashCodeBuilder; 10 | import org.apache.commons.lang.builder.ToStringBuilder; 11 | 12 | @Entity 13 | public class Item { 14 | 15 | @Id 16 | @GeneratedValue 17 | private Long id; 18 | 19 | @Column(nullable = false) 20 | private String name; 21 | 22 | @Column(nullable = false) 23 | private double price; 24 | 25 | public Item() { 26 | super(); 27 | id = 0l; 28 | } 29 | 30 | public Item(String name, double price) { 31 | super(); 32 | this.name = name; 33 | this.price = price; 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public void setName(String name) { 41 | this.name = name; 42 | } 43 | 44 | public double getPrice() { 45 | return price; 46 | } 47 | 48 | public void setPrice(double price) { 49 | this.price = price; 50 | } 51 | 52 | public Long getId() { 53 | return id; 54 | } 55 | 56 | public void setId(Long id) { 57 | this.id = id; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return ToStringBuilder.reflectionToString(this); 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | return HashCodeBuilder.reflectionHashCode(this); 68 | 69 | } 70 | 71 | @Override 72 | public boolean equals(Object obj) { 73 | return EqualsBuilder.reflectionEquals(this, obj); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/java/com/ewolff/microservice/catalog/ItemRepository.java: -------------------------------------------------------------------------------- 1 | package com.ewolff.microservice.catalog; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.PagingAndSortingRepository; 6 | import org.springframework.data.repository.query.Param; 7 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 8 | 9 | @RepositoryRestResource(collectionResourceRel = "catalog", path = "catalog") 10 | public interface ItemRepository extends PagingAndSortingRepository { 11 | 12 | List findByName(@Param("name") String name); 13 | 14 | List findByNameContaining(@Param("name") String name); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/java/com/ewolff/microservice/catalog/SpringRestDataConfig.java: -------------------------------------------------------------------------------- 1 | package com.ewolff.microservice.catalog; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.rest.core.config.RepositoryRestConfiguration; 6 | import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; 7 | import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; 8 | 9 | @Configuration 10 | class SpringRestDataConfig extends RepositoryRestConfigurerAdapter { 11 | 12 | @Bean 13 | public RepositoryRestConfigurer repositoryRestConfigurer() { 14 | 15 | return new RepositoryRestConfigurerAdapter() { 16 | @Override 17 | public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { 18 | config.exposeIdsFor(Item.class); 19 | } 20 | }; 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/java/com/ewolff/microservice/catalog/web/CatalogController.java: -------------------------------------------------------------------------------- 1 | package com.ewolff.microservice.catalog.web; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RequestParam; 10 | import org.springframework.web.servlet.ModelAndView; 11 | 12 | import com.ewolff.microservice.catalog.Item; 13 | import com.ewolff.microservice.catalog.ItemRepository; 14 | 15 | @Controller 16 | public class CatalogController { 17 | 18 | private final ItemRepository itemRepository; 19 | 20 | @Autowired 21 | public CatalogController(ItemRepository itemRepository) { 22 | this.itemRepository = itemRepository; 23 | } 24 | 25 | @RequestMapping(value = "/{id}.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE) 26 | public ModelAndView Item(@PathVariable("id") long id) { 27 | return new ModelAndView("item", "item", itemRepository.findById(id).get()); 28 | } 29 | 30 | @RequestMapping(value = "/list.html", method = RequestMethod.GET) 31 | public ModelAndView ItemList() { 32 | return new ModelAndView("itemlist", "items", itemRepository.findAll()); 33 | } 34 | 35 | @RequestMapping(value = "/form.html", method = RequestMethod.GET) 36 | public ModelAndView add() { 37 | return new ModelAndView("item", "item", new Item()); 38 | } 39 | 40 | @RequestMapping(value = "/form.html", method = RequestMethod.POST) 41 | public ModelAndView post(Item Item) { 42 | Item = itemRepository.save(Item); 43 | return new ModelAndView("success"); 44 | } 45 | 46 | @RequestMapping(value = "/{id}.html", method = RequestMethod.PUT) 47 | public ModelAndView put(@PathVariable("id") long id, Item item) { 48 | item.setId(id); 49 | itemRepository.save(item); 50 | return new ModelAndView("success"); 51 | } 52 | 53 | @RequestMapping(value = "/searchForm.html", produces = MediaType.TEXT_HTML_VALUE, method = RequestMethod.GET) 54 | public ModelAndView searchForm() { 55 | return new ModelAndView("searchForm"); 56 | } 57 | 58 | @RequestMapping(value = "/searchByName.html", produces = MediaType.TEXT_HTML_VALUE, method = RequestMethod.GET) 59 | public ModelAndView search(@RequestParam("query") String query) { 60 | return new ModelAndView("itemlist", "items", itemRepository.findByNameContaining(query)); 61 | } 62 | 63 | @RequestMapping(value = "/{id}.html", method = RequestMethod.DELETE) 64 | public ModelAndView delete(@PathVariable("id") long id) { 65 | itemRepository.deleteById(id); 66 | return new ModelAndView("success"); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8080 2 | management.endpoints.web.exposure.include=* 3 | spring.cloud.refresh.refreshable=none 4 | logging.level.org.springframework.boot.actuate.trace.WebRequestTraceFilter: TRACE 5 | spring.application.name=catalog 6 | eureka.client.serviceUrl.defaultZone=http://eureka:8761/eureka/ 7 | eureka.instance.leaseRenewalIntervalInSeconds=5 8 | # leave eureka.instance.leaseRenewalIntervalInSeconds unchanged in production 9 | # just here to provide quicker updates to Eureka for demos 10 | eureka.instance.metadataMap.instanceId=${spring.application.name}:${random.value} 11 | eureka.instance.preferIpAddress=true 12 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | spring.cloud.config.enabled=false -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/resources/templates/item.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Item : Edit 7 | 8 | 9 |

Item : Edit

10 |
11 |
13 |
14 | 16 |
17 | 18 |
19 | 22 |
23 | 24 |
25 |
26 | 27 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/resources/templates/itemlist.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Item : View all 7 | 8 | 9 |

Item : View all

10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 33 | 34 | 35 |
idNamePrice
No items
1Name42.0
31 | 32 |
36 |
37 |
38 | Add Item 39 |
40 |
41 |
42 | 43 | -------------------------------------------------------------------------------- /microservice-demo/microservice-demo-catalog/src/main/resources/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Layout 7 | 9 | 11 | 12 | 13 | 14 |
15 | 23 |

Layout

24 |
Fake content
25 |
26 | 14 | 15 | 16 | 17 |

Order Processing

18 |
19 |
20 |
21 | Customer 22 |
23 |
List / add / remove customers
24 |
25 |
26 |
27 | Catalog 28 |
29 |
List / add / remove items
30 |
31 |
32 |
33 | Catalog 34 |
35 |
Search Items
36 |
37 |
38 |
39 | Order 40 |
41 |
Create an order
42 |
43 |
44 |
45 |
46 |
47 | Eureka (Vagrant) 48 |
49 |
Service discovery
50 |
51 |
52 | 55 |
Service discovery
56 |
57 |
58 | 61 |
Monitor state of 62 | Hystrix
63 |
64 |
65 | 68 |
Monitor state of 69 | Hystrix
70 |
71 | 72 |
73 | 74 | 75 | -------------------------------------------------------------------------------- /microservice-demo/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | ########################################################################################## 204 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 205 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 206 | ########################################################################################## 207 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 208 | if [ "$MVNW_VERBOSE" = true ]; then 209 | echo "Found .mvn/wrapper/maven-wrapper.jar" 210 | fi 211 | else 212 | if [ "$MVNW_VERBOSE" = true ]; then 213 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 214 | fi 215 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 216 | while IFS="=" read key value; do 217 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 218 | esac 219 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 220 | if [ "$MVNW_VERBOSE" = true ]; then 221 | echo "Downloading from: $jarUrl" 222 | fi 223 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 224 | 225 | if command -v wget > /dev/null; then 226 | if [ "$MVNW_VERBOSE" = true ]; then 227 | echo "Found wget ... using wget" 228 | fi 229 | wget "$jarUrl" -O "$wrapperJarPath" 230 | elif command -v curl > /dev/null; then 231 | if [ "$MVNW_VERBOSE" = true ]; then 232 | echo "Found curl ... using curl" 233 | fi 234 | curl -o "$wrapperJarPath" "$jarUrl" 235 | else 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Falling back to using Java to download" 238 | fi 239 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 240 | if [ -e "$javaClass" ]; then 241 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 242 | if [ "$MVNW_VERBOSE" = true ]; then 243 | echo " - Compiling MavenWrapperDownloader.java ..." 244 | fi 245 | # Compiling the Java class 246 | ("$JAVA_HOME/bin/javac" "$javaClass") 247 | fi 248 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 249 | # Running the downloader 250 | if [ "$MVNW_VERBOSE" = true ]; then 251 | echo " - Running MavenWrapperDownloader.java ..." 252 | fi 253 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 254 | fi 255 | fi 256 | fi 257 | fi 258 | ########################################################################################## 259 | # End of extension 260 | ########################################################################################## 261 | 262 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 263 | if [ "$MVNW_VERBOSE" = true ]; then 264 | echo $MAVEN_PROJECTBASEDIR 265 | fi 266 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 267 | 268 | # For Cygwin, switch paths to Windows format before running java 269 | if $cygwin; then 270 | [ -n "$M2_HOME" ] && 271 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 272 | [ -n "$JAVA_HOME" ] && 273 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 274 | [ -n "$CLASSPATH" ] && 275 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 276 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 277 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 278 | fi 279 | 280 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 281 | 282 | exec "$JAVACMD" \ 283 | $MAVEN_OPTS \ 284 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 285 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 286 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 287 | -------------------------------------------------------------------------------- /microservice-demo/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /microservice-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | org.springframework.cloud 6 | spring-cloud-starter-parent 7 | Hoxton.SR8 8 | 9 | 10 | 11 | 4.0.0 12 | com.ewolff 13 | microservice-demo 14 | 0.0.1-SNAPSHOT 15 | pom 16 | 17 | 18 | microservice-demo-eureka-server 19 | microservice-demo-turbine-server 20 | microservice-demo-customer 21 | microservice-demo-catalog 22 | microservice-demo-order 23 | microservice-demo-zuul-server 24 | 25 | 26 | 27 | 11 28 | 29 | 30 | 31 | 32 | 33 | org.webjars 34 | bootstrap 35 | 3.3.6 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /scripts/README.md: -------------------------------------------------------------------------------- 1 | Some utility script. 2 | 3 | * createdemo.sh create a Docker Machine based environment for the demo 4 | * destroydemo.sh destroy the Docker Machine environment -------------------------------------------------------------------------------- /scripts/createdemo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd microservice-demo 3 | mvn package 4 | cd .. 5 | cd docker 6 | docker-machine create --virtualbox-memory "4096" --driver virtualbox ms 7 | eval "$(docker-machine env ms)" 8 | docker-compose build 9 | -------------------------------------------------------------------------------- /scripts/destroydemo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | docker-machine rm ms 3 | --------------------------------------------------------------------------------