Skip to content

Commit 0f0d6b4

Browse files
committed
Merge branch 'release/0.1'
2 parents 532807d + 983c5a8 commit 0f0d6b4

File tree

53 files changed

+2676
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2676
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,6 @@ build/
5353

5454
### VS Code ###
5555
.vscode/
56+
57+
## Drawio source files ##
58+
*.drawio
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright 2007-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import java.net.*;
17+
import java.io.*;
18+
import java.nio.channels.*;
19+
import java.util.Properties;
20+
21+
public class MavenWrapperDownloader {
22+
23+
private static final String WRAPPER_VERSION = "0.5.6";
24+
/**
25+
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
26+
*/
27+
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
28+
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
29+
30+
/**
31+
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
32+
* use instead of the default one.
33+
*/
34+
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
35+
".mvn/wrapper/maven-wrapper.properties";
36+
37+
/**
38+
* Path where the maven-wrapper.jar will be saved to.
39+
*/
40+
private static final String MAVEN_WRAPPER_JAR_PATH =
41+
".mvn/wrapper/maven-wrapper.jar";
42+
43+
/**
44+
* Name of the property which should be used to override the default download url for the wrapper.
45+
*/
46+
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
47+
48+
public static void main(String args[]) {
49+
System.out.println("- Downloader started");
50+
File baseDirectory = new File(args[0]);
51+
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
52+
53+
// If the maven-wrapper.properties exists, read it and check if it contains a custom
54+
// wrapperUrl parameter.
55+
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
56+
String url = DEFAULT_DOWNLOAD_URL;
57+
if(mavenWrapperPropertyFile.exists()) {
58+
FileInputStream mavenWrapperPropertyFileInputStream = null;
59+
try {
60+
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
61+
Properties mavenWrapperProperties = new Properties();
62+
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
63+
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
64+
} catch (IOException e) {
65+
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
66+
} finally {
67+
try {
68+
if(mavenWrapperPropertyFileInputStream != null) {
69+
mavenWrapperPropertyFileInputStream.close();
70+
}
71+
} catch (IOException e) {
72+
// Ignore ...
73+
}
74+
}
75+
}
76+
System.out.println("- Downloading from: " + url);
77+
78+
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
79+
if(!outputFile.getParentFile().exists()) {
80+
if(!outputFile.getParentFile().mkdirs()) {
81+
System.out.println(
82+
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
83+
}
84+
}
85+
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
86+
try {
87+
downloadFileFromURL(url, outputFile);
88+
System.out.println("Done");
89+
System.exit(0);
90+
} catch (Throwable e) {
91+
System.out.println("- Error downloading");
92+
e.printStackTrace();
93+
System.exit(1);
94+
}
95+
}
96+
97+
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
98+
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
99+
String username = System.getenv("MVNW_USERNAME");
100+
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
101+
Authenticator.setDefault(new Authenticator() {
102+
@Override
103+
protected PasswordAuthentication getPasswordAuthentication() {
104+
return new PasswordAuthentication(username, password);
105+
}
106+
});
107+
}
108+
URL website = new URL(urlString);
109+
ReadableByteChannel rbc;
110+
rbc = Channels.newChannel(website.openStream());
111+
FileOutputStream fos = new FileOutputStream(destination);
112+
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
113+
fos.close();
114+
rbc.close();
115+
}
116+
117+
}

.mvn/wrapper/maven-wrapper.jar

49.5 KB
Binary file not shown.

.mvn/wrapper/maven-wrapper.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2+
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

README.md

Lines changed: 225 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,225 @@
1-
# Springy Store Microservices
2-
This project is a development of a small set of Microservices spring boot based projects, that implement cloud-native recommendations to show how Microservices should be built, using the following cutting edge technologies like Docker, Kubernetes, Elasticsearch Stack, Java SE 14, MySQL database, MongoDB, and Reactive Programming, with many more.
1+
# Springy Store μServices
2+
3+
- This project is a development of a small set of Spring Boot based Microservices projects, that implement cloud-native intuitive, design patterns and coding best practices.
4+
- The project follows [**CloudNative**](https://www.cncf.io/) recommendations and The [**twelve-factor app**](https://12factor.net/) methodology for building *software-as-a-service apps* to show how μServices should be built and deployed.
5+
- The project is using cutting edge technologies like Docker, Kubernetes, Elasticsearch Stack for logging and monitoring, Java SE 14, MySQL database, MongoDB, TDD, unit, integration & performance testing and Reactive Programming, and many more.
6+
7+
------
8+
9+
I am developing this project as stages, and all such stages are documented under project **Springy Store μServices** [wiki page](https://github.com/mohamed-taman/Springy-Store-Microservices/wiki). each such stage will be a release so you can go back and forward between releases to see the differences and how adding things solve specific problems we face.
10+
11+
For example; in the first stage (1st release) I just created project structure, basic services skeleton, integration between them, and finally write integration testing as well as semi-automated testing for the whole services functionality.
12+
13+
At 1st stage the **recommendation** and **review** microservices generate local in-memory data and **product composite service** calls the other three services (*product*, *recommendation*, and *review*) statically to generate client aggregate response for a specific product. Therefore in:
14+
15+
- The second stage I will introduce **database integration**, then in
16+
- The third stage I will introduce **Dockerization** of our services and **docker-compose**, and in
17+
- The fourth stage I will introduce **service discovery**, and so on.
18+
19+
## Getting started
20+
21+
The first stage aka (**Release v1.0**) is about creating and implementing a set of project Microservices.
22+
23+
### Creating a Set of Cooperating Microservices
24+
25+
The following topics are covered in this 1st stage (other stages topics will be documented in a project wiki):
26+
27+
- Introducing the microservice landscape.
28+
- Generating skeleton microservices.
29+
- Adding RESTful APIs.
30+
- Adding a **product composite**, **product**, **recommendation**, and **review** microservices.
31+
- Adding error handling.
32+
- Testing the APIs manually.
33+
- Adding automated tests of microservices in isolation.
34+
- Adding semi-automated tests to a microservice landscape.
35+
36+
### System Boundary - μServices Landscape
37+
38+
![System Boundary](docs/stage1/Springy%20Store%20Application%20MS%20Landscape.png)
39+
40+
### Required software
41+
42+
The following software pieces are initially required:
43+
44+
1. **Git**: it can be downloaded and installed from https://git-scm.com/downloads.
45+
46+
2. **Java 14**: it can be downloaded and installed from https://www.oracle.com/technetwork/java/javase/downloads/index.html.
47+
48+
3. **curl**: this command-line tool for testing HTTP-based APIs can be downloaded and installed from https://curl.haxx.se/download.html.
49+
50+
4. **jq**: This command-line JSON processor can be downloaded and installed from https://stedolan.github.io/jq/download/.
51+
52+
5. Spring Boot Initializer: This *Initializer* generates *spring* boot project with just what you need to start quickly! start from here https://start.spring.io/.
53+
54+
> For each future stage, I will list the newly required software.
55+
56+
Follow the installation guide for each software website and check your software versions from the command line to verify that they are installed correctly.
57+
58+
## Using an IDE
59+
60+
I recommend that you work with your Java code using an IDE that supports the development of Spring Boot applications such as Spring Tool Suite or IntelliJ IDEA Ultimate Edition. So you can use the Spring Boot Dashboard to run the services, run each microservice test case and many more.
61+
62+
All that you want to do is just fire up your IDE **->** open or import the parent folder `springy-store-microservices` and everything will be ready for you.
63+
64+
## Playing With Spring Store Project
65+
66+
### Cloning It
67+
68+
First open **git bash** command line, then simply you can clone the project under any of your favorite places as the following:
69+
70+
```bash
71+
> git clone https://github.com/mohamed-taman/Springy-Store-Microservices.git
72+
```
73+
74+
### Build & Test Them In Isolation
75+
76+
To build and run test cases for each service & shared modules in the project we need to do the following:
77+
78+
#### First: Build & Install Shared Dependencies
79+
80+
> This is done for the first time only or any new version of shared modules..
81+
82+
To build and install `store-utils`, `store-api`, `store-chassis` libraries, from the root folder `springy-store-microservices` run the following commands:
83+
84+
```bash
85+
mohamed.taman@DTLNV8 ~/springy-store-microservices
86+
λ ./setup.sh
87+
```
88+
89+
and you should expect output like this:
90+
91+
```bash
92+
mohamed.taman@DTLNV8 ~/Springy Store Microservices
93+
λ ./setup.sh
94+
95+
Installing all Springy store core shared modules
96+
................................................
97+
98+
1- Installing shared [Utilities] module...
99+
Done successfully.
100+
101+
2- Installing shared [APIs] module...
102+
Done successfully.
103+
104+
3- Installing [parent project] module...
105+
Done successfully.
106+
107+
Wooohooo, building & installing all project modules are finished successfully.
108+
and the project is ready for the next step. :)
109+
```
110+
111+
#### Second: Build & Test Microservices
112+
113+
Now it is time to build our **4 microservices** and run each service integration test in isolation by running the following commands:
114+
115+
```bash
116+
mohamed.taman@DTLNV8 ~/springy-store-microservices
117+
λ cd store-chassis
118+
mohamed.taman@DTLNV8 ~/springy-store-microservices/store-chassis
119+
λ mvn clean verify
120+
```
121+
122+
All build commands and test suite for each microservice should run successfully and the final output should be like this:
123+
124+
```bash
125+
[INFO] ------------------------------------------------------------------------
126+
[INFO] Reactor Summary:
127+
[INFO]
128+
[INFO] Springy Store APIs 1.0-SNAPSHOT .................... SUCCESS [ 3.048 s]
129+
[INFO] Springy Store Utils 1.0-SNAPSHOT ................... SUCCESS [ 2.107 s]
130+
[INFO] Springy Store Chassis 0.0.1-SNAPSHOT ............... SUCCESS [ 0.865 s]
131+
[INFO] Product Composite Service 0.0.1-SNAPSHOT ........... SUCCESS [ 11.086 s]
132+
[INFO] Product Service 0.0.1-SNAPSHOT ..................... SUCCESS [ 9.795 s]
133+
[INFO] Review Service 0.0.1-SNAPSHOT ...................... SUCCESS [ 9.214 s]
134+
[INFO] Recommendation Service 0.0.1-SNAPSHOT .............. SUCCESS [ 9.288 s]
135+
[INFO] ------------------------------------------------------------------------
136+
[INFO] BUILD SUCCESS
137+
[INFO] ------------------------------------------------------------------------
138+
[INFO] Total time: 46.006 s
139+
[INFO] Finished at: 2020-04-01T17:07:52+02:00
140+
[INFO] ------------------------------------------------------------------------
141+
```
142+
143+
### Running Them
144+
145+
Now it is time to run all of them, and it is very simple just run the following two commands:
146+
147+
```bash
148+
mohamed.taman@DTLNV8 ~/springy-store-microservices/store-chassis
149+
λ cd ..
150+
mohamed.taman@DTLNV8 ~/springy-store-microservices
151+
λ ./run-em-all.sh
152+
```
153+
154+
All the services will run in parallel and their output will be printed to the console.
155+
156+
### Testing Them All
157+
158+
Now it is time to test all functionality of the application as one part. and to do so just run the following automation test script:
159+
160+
```bash
161+
mohamed.taman@DTLNV8 ~/springy-store-microservices
162+
λ ./test-em-all.sh
163+
```
164+
165+
The result should be something like this:
166+
167+
```bash
168+
Starting [Springy Store] full functionality testing....
169+
170+
HOST=localhost
171+
PORT=9080
172+
Test OK (HTTP Code: 200)
173+
Test OK (actual value: 1)
174+
Test OK (actual value: 3)
175+
Test OK (actual value: 3)
176+
Test OK (HTTP Code: 404, {"httpStatus":"NOT_FOUND","message":"No product found for productId: 13","path":"/product-composite/13","time":"2020-04-01@14:51:48.812+0200"})
177+
Test OK (HTTP Code: 200)
178+
Test OK (actual value: 113)
179+
Test OK (actual value: 0)
180+
Test OK (actual value: 3)
181+
Test OK (HTTP Code: 200)
182+
Test OK (actual value: 213)
183+
Test OK (actual value: 3)
184+
Test OK (actual value: 0)
185+
Test OK (HTTP Code: 422, {"httpStatus":"UNPROCESSABLE_ENTITY","message":"Invalid productId: -1","path":"/product-composite/-1","time":"2020-04-01@14:51:49.763+0200"})
186+
Test OK (actual value: "Invalid productId: -1")
187+
Test OK (HTTP Code: 400, {"timestamp":"2020-04-01T12:51:49.965+0000","path":"/product-composite/invalidProductId","status":400,"error":"Bad Request","message":"Type mismatch."})
188+
Test OK (actual value: "Type mismatch.")
189+
```
190+
191+
### Closing The Story
192+
193+
And to close the story, we will need to shutdown Microservices manually service by service, hahaha just kidding, run the following script to shutdown them all:
194+
195+
```bash
196+
mohamed.taman@DTLNV8 ~/springy-store-microservices
197+
λ ./stop-em-all.sh
198+
```
199+
200+
and the output should be as the following:
201+
202+
```bash
203+
Stopping [Springy Store] μServices ....
204+
---------------------------------------
205+
206+
Stopping Microservice at port 9080 ....
207+
{"message":"Shutting down, bye..."}
208+
Microservice at port 9080 stopped successfully ....
209+
210+
Stopping Microservice at port 9081 ....
211+
{"message":"Shutting down, bye..."}
212+
Microservice at port 9081 stopped successfully ....
213+
214+
Stopping Microservice at port 9082 ....
215+
{"message":"Shutting down, bye..."}
216+
Microservice at port 9082 stopped successfully ....
217+
218+
Stopping Microservice at port 9083 ....
219+
{"message":"Shutting down, bye..."}
220+
Microservice at port 9083 stopped successfully ....
221+
```
222+
223+
### The End
224+
225+
Happy coding :)
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="Electron" modified="2020-04-01T16:42:39.773Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/12.9.3 Chrome/80.0.3987.158 Electron/8.2.0 Safari/537.36" etag="fDBcLv3HnAtoRhQ4TFjc" version="12.9.3" type="device"><diagram id="_t4D4tSkYDaTQ3sDm7r4" name="Page-1">7VpZk6M2EP41fvQUh8H249ieTVI1W7W1diXZfZOhObICESF85NdHAmHAgA3seDxJ2fMwqLt19PV1I3ukL4PDLxRF3mdiAx5pin0Y6auRpqmKNuH/BOWYUYy5lhFc6ttSqCCs/X8gnympiW9DXBFkhGDmR1WiRcIQLFahIUrJvirmEFzdNUIu1AhrC+E69Q/fZp6kqua8YPwKvuvJrWfaNGMEKBeWmsQessm+RNJfRvqSEsKyp+CwBCyMl9slm/ephXs6GIWQdZnAQjc8qGOydTYINr99M8zvX8czeTZ2zBUGm+svh4Qyj7gkRPiloC4oSUIbxKoKHxUyr4REnKhy4l/A2FE6EyWMcJLHAiy52Z5io1ZVJCkmCbXgwvnzkEDUBXZBzjgZnEcqkAAYPfJ5FDBi/q56DiRDxj3JFVblD9KwPYysqvewMrclPf4p5j8Z+fCbXC4drA6V0VGO7uCd6V29oz28c9E75l29k627QziRO400E/PjLhzCFS67zfw7ITljHKeGf+YC6jQ6FEz+5Ir/XyixE0sssCRBRGKfQb4wP2e2diaZk7f0nCJPYBFMaOUEI01X+Gc+r+9bnVulxREKO2lkCI2yaFBS3l5WIMENCQ0QbtjZWJQ0zPbquP/e4+YZc7YlTxBRGO95wR9wir7eM5q8N1q+jBbLKw7rq+UgK5f5Dgp8fMz4fFkURFks6BOBERGk26IwrvFS+WXTLAsDov2neYB3wHwLiZNCAsOmdp6DqJ/6ukVeHH4cA/Wdk70uRNS5r9dAd74FV7zaEgP9wqx/Sq2ux2CVfFZpijqi5nm2zoyySq1RqRmOj/HyBDa6jWDmWCKiGSU/oMQxrRlsHallXsjUfJyVJNU4nWcHlMHhcj2p47+cMMk7ddngq6Yc74t2WVONjOaVOuVc7s1LhtFaMjqnfmPJOBWCnPAVdj7sS67eNri/KVi39Odjcqoo7dl0DX0HYWDvXQbVR6PjIR9gewuwzQrrFcjtgnrVsH9f1HsDVDPNKqrpyr1RzXw/VLNIEEBo8+6ehA90e6DbA93+Z+imfjh0mw58ze+NGWXA6XxHcPVe4AF3D7h7wN1HhbvzV9T7w506/S/dOTffGrzNHbTe8RK6xcPvdAmt18rTEvtC2XMvxh6KxGMS4GeLiWBeiNDloIBf0RbwF3HTLNpqfbUljJGAC2DBWCDrh5t6uJQETvoprfGMfVfMZeQsr0jCsB/yBMq/BW3320+lkqFoT0Y1mfRaLunKe6bSvLV18NTGiiMMNfZK1VfTeWFsbAtmknGOrBuvKAzhNo66VON24O61dbe+qMtCA+7Q47yWKK8otGNLBHshKezdUiR4xLFqxFYRPyQhnJUHSUIy5DE4rCETAt+2U3RsKjxVxCynw0yOP8nGY/U7UBuF6Eb99WxSLzhGQ5bot8qS/EcI5SwxFutjzCDg5IUwFOL7GKsP67oGV5U9OpHjEnxODfF3G5dO8hJecqna5FLtZi7V2oFP6/yOILw7lo4ScGFxewAdADs1VBWxbHR94Wp/rxC9Wu0roYj6oSu8s+Y1VsDRcxRhHltnN1Y9vhUU8FWzWtSxflzUdHLp1q0zijeu8pzwHpBmEp+JhwKeMJqyQQHqYIVooLb3UpanfZx2TkJkpz4pvVR8M1ATBZwHHycYxWiTduDj1CpNaEY49jg4/fWXx1GPv88OQDizjnBm+qlD7Q0AT6u/M+lqA96pan/A48Pid3Apr/RrQv3lXw==</diagram></mxfile>

0 commit comments

Comments
 (0)