mirror of
https://github.com/spring-cloud/spring-cloud-netflix.git
synced 2026-09-18 16:19:18 +00:00
Compare commits
647
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ad4f3d7e8 | ||
|
|
e5ccca6c2b | ||
|
|
5ec430efb8 | ||
|
|
f6f4e0d80d | ||
|
|
e8976ae344 | ||
|
|
09adda65c0 | ||
|
|
a3cfba7e3b | ||
|
|
f76de4c481 | ||
|
|
6316953236 | ||
|
|
3a91f2372c | ||
|
|
4f2ddfd2ec | ||
|
|
dff98c48dd | ||
|
|
4c77b6dd5d | ||
|
|
d0f8fbe274 | ||
|
|
67c227d9d7 | ||
|
|
a30b87cdda | ||
|
|
01f72ff328 | ||
|
|
20a3671055 | ||
|
|
01c2c04162 | ||
|
|
2497900d3e | ||
|
|
65fb24e321 | ||
|
|
0188b2511d | ||
|
|
c6a7ebb918 | ||
|
|
9d6e3523dd | ||
|
|
38e6b0b2b5 | ||
|
|
1229e07636 | ||
|
|
852e72f5e6 | ||
|
|
8b2b6b5115 | ||
|
|
f015f5cad4 | ||
|
|
612b6edb41 | ||
|
|
b633c8af96 | ||
|
|
079ae668c0 | ||
|
|
3af988adcf | ||
|
|
a5e038cf13 | ||
|
|
b8af1db32f | ||
|
|
d831ca31c3 | ||
|
|
ec903900c9 | ||
|
|
9b6b0aba4e | ||
|
|
e5a52ee5ac | ||
|
|
6548e0dab6 | ||
|
|
9e1f7f6aad | ||
|
|
2899b42107 | ||
|
|
a06f6e98bd | ||
|
|
2b51d15d87 | ||
|
|
cb3cc3234f | ||
|
|
b11c4c9b20 | ||
|
|
4b5d0a0b86 | ||
|
|
4fda5b40b8 | ||
|
|
719688f4c8 | ||
|
|
162b1c8a9b | ||
|
|
872d64494b | ||
|
|
96b10d40c3 | ||
|
|
28f1848b85 | ||
|
|
83c74b0017 | ||
|
|
27ac3379f6 | ||
|
|
e38cd1ef66 | ||
|
|
a1a6ee244c | ||
|
|
2a31d0e121 | ||
|
|
93913603eb | ||
|
|
6aafd20d60 | ||
|
|
cdf89659e8 | ||
|
|
1efa843ed8 | ||
|
|
fab3190ca4 | ||
|
|
eafecd3b6a | ||
|
|
2c22afa8bd | ||
|
|
e33e5a54f6 | ||
|
|
e757479f85 | ||
|
|
c350c88267 | ||
|
|
827be605b3 | ||
|
|
e5ba2575e6 | ||
|
|
8f9797627f | ||
|
|
75d77cd38e | ||
|
|
b518187da8 | ||
|
|
c94923d0ce | ||
|
|
2532e3a263 | ||
|
|
fef3a9ea78 | ||
|
|
dd80e2b23b | ||
|
|
872ac78396 | ||
|
|
91790a55a7 | ||
|
|
927a51c21c | ||
|
|
39b4c8b578 | ||
|
|
5da06943c0 | ||
|
|
912fa949ff | ||
|
|
292b2ec83e | ||
|
|
d5637172f2 | ||
|
|
b7bfc42697 | ||
|
|
a86dba2659 | ||
|
|
76ab698306 | ||
|
|
df6df5d1dd | ||
|
|
53392471a5 | ||
|
|
c6c6783a0a | ||
|
|
848c306d67 | ||
|
|
a70946fce5 | ||
|
|
6303a7ea03 | ||
|
|
dc67500445 | ||
|
|
ed3834f781 | ||
|
|
a4b06d37b7 | ||
|
|
d71040222b | ||
|
|
1327bcb7d0 | ||
|
|
f1ebbb98e8 | ||
|
|
dc45b7f580 | ||
|
|
d5aa729711 | ||
|
|
88d8e08349 | ||
|
|
c9c737c11c | ||
|
|
519c1d2aaf | ||
|
|
d925a03343 | ||
|
|
e4e1003dd8 | ||
|
|
1d9e0d5499 | ||
|
|
8419b9b876 | ||
|
|
5675aec402 | ||
|
|
829c1773cf | ||
|
|
bf8ba5c7b5 | ||
|
|
d532f4de31 | ||
|
|
44fa4a226e | ||
|
|
0490150344 | ||
|
|
6356c11b45 | ||
|
|
86797d0f12 | ||
|
|
bf7699f4e6 | ||
|
|
3c8e8feeea | ||
|
|
45f2998b0b | ||
|
|
1a0f10e79d | ||
|
|
960fb64e39 | ||
|
|
02100d9d46 | ||
|
|
432eaa0d76 | ||
|
|
247832e106 | ||
|
|
5cf48fadfb | ||
|
|
59deb14e38 | ||
|
|
76b21a4a2a | ||
|
|
8cbb4dbe20 | ||
|
|
81ee8de8a2 | ||
|
|
aeeee56edc | ||
|
|
cf9c645f4a | ||
|
|
12ffaf1005 | ||
|
|
2b10f19d1a | ||
|
|
96eb785d07 | ||
|
|
d79b43fd28 | ||
|
|
f4baba128d | ||
|
|
ac2d4888b5 | ||
|
|
3a402fbef5 | ||
|
|
6b165d83f0 | ||
|
|
cac519d89c | ||
|
|
04937f0113 | ||
|
|
e723f67f5a | ||
|
|
2176987868 | ||
|
|
1d46777c20 | ||
|
|
3e60fd4096 | ||
|
|
89c37a3842 | ||
|
|
17e72988dc | ||
|
|
849f1e7e99 | ||
|
|
3f4c702aa5 | ||
|
|
907c85f7c2 | ||
|
|
1bd64613d1 | ||
|
|
6648caf96d | ||
|
|
80e4408de7 | ||
|
|
86101cd733 | ||
|
|
1cb2aa34d3 | ||
|
|
a5734695b7 | ||
|
|
14c7ac2dda | ||
|
|
f151c881de | ||
|
|
e839d1dfbd | ||
|
|
6ad1ab2c76 | ||
|
|
e8ed3c3bd1 | ||
|
|
c5268f0d89 | ||
|
|
2b33f7a8b6 | ||
|
|
848bfab4ee | ||
|
|
4646484a30 | ||
|
|
6f1332ee72 | ||
|
|
98048189dd | ||
|
|
43fe8c1e62 | ||
|
|
ec6b111956 | ||
|
|
a1e166a814 | ||
|
|
a562fd0815 | ||
|
|
d9bc811fac | ||
|
|
806025307e | ||
|
|
92e7f572ba | ||
|
|
bff9419201 | ||
|
|
7b90195ee8 | ||
|
|
df7ecf81c9 | ||
|
|
e2236a816e | ||
|
|
f2526d5e03 | ||
|
|
8e00d28bcc | ||
|
|
92cb1a7aa0 | ||
|
|
8ecb3dca51 | ||
|
|
53e3639366 | ||
|
|
c145e4610d | ||
|
|
659a97ad63 | ||
|
|
51918d1659 | ||
|
|
63134d9f47 | ||
|
|
df64a02013 | ||
|
|
2aedbcaaa6 | ||
|
|
74f7c0eefd | ||
|
|
47e4d6396b | ||
|
|
ca65e05acb | ||
|
|
bb72b973bf | ||
|
|
4978f8f7de | ||
|
|
0b490f6d27 | ||
|
|
0092fb50d9 | ||
|
|
c6141c5b15 | ||
|
|
992269781a | ||
|
|
1d6a5876fb | ||
|
|
de5d517bfe | ||
|
|
7bf8f60c0e | ||
|
|
cdbbb7ad10 | ||
|
|
47c678f53b | ||
|
|
5d19ac3b08 | ||
|
|
9c40720aa6 | ||
|
|
1e45946555 | ||
|
|
e44e36d31a | ||
|
|
5d2942158c | ||
|
|
e181683a00 | ||
|
|
b6ed99eb9b | ||
|
|
c862f34779 | ||
|
|
5297985e61 | ||
|
|
eef49656e0 | ||
|
|
4ec5556420 | ||
|
|
2fe021fbdb | ||
|
|
a452c1d8e9 | ||
|
|
3bf50f3ef5 | ||
|
|
d384bd29c3 | ||
|
|
191b889994 | ||
|
|
300fe19ca0 | ||
|
|
b6badeb556 | ||
|
|
ab17bbfee2 | ||
|
|
7240308834 | ||
|
|
53c5b4ba86 | ||
|
|
da54b740f3 | ||
|
|
48a044cc71 | ||
|
|
839a780e54 | ||
|
|
ce82ea3b71 | ||
|
|
99ebcfb79a | ||
|
|
08add768d0 | ||
|
|
4064646b39 | ||
|
|
c1352a8132 | ||
|
|
ce73a587f5 | ||
|
|
13337db454 | ||
|
|
78ca251e96 | ||
|
|
658599f810 | ||
|
|
281f68c4e4 | ||
|
|
0e2cd26a4a | ||
|
|
6ce8123be1 | ||
|
|
d11f91cdb1 | ||
|
|
57053ed7eb | ||
|
|
0297304397 | ||
|
|
4bdb799c8c | ||
|
|
6e70f55049 | ||
|
|
be57fe3d8b | ||
|
|
931cca4f44 | ||
|
|
036685e153 | ||
|
|
06d6daad88 | ||
|
|
27248f12d0 | ||
|
|
8eb11b5730 | ||
|
|
6640f3b577 | ||
|
|
0665640c97 | ||
|
|
8125e3261a | ||
|
|
40ee698777 | ||
|
|
0d7c73c583 | ||
|
|
965d1cb168 | ||
|
|
ba53b6a551 | ||
|
|
d498a6e091 | ||
|
|
34ede67962 | ||
|
|
24e842cfdd | ||
|
|
a1a9d8c599 | ||
|
|
a25d364062 | ||
|
|
c5e8b66368 | ||
|
|
2b0ea67e3d | ||
|
|
88985f33af | ||
|
|
eeaeeb3e6f | ||
|
|
a3436d08eb | ||
|
|
5f3f35fd68 | ||
|
|
c60b6dba52 | ||
|
|
23d15f70bc | ||
|
|
072418826e | ||
|
|
cbc914259b | ||
|
|
896b33c109 | ||
|
|
a826a960e6 | ||
|
|
a579eb4594 | ||
|
|
624bbc8b50 | ||
|
|
2e42e37677 | ||
|
|
4de8761123 | ||
|
|
34d956ae5b | ||
|
|
8d5a3f8ec1 | ||
|
|
f6120d525f | ||
|
|
4bf57b9cd2 | ||
|
|
f6f2f4726b | ||
|
|
c56bee9cfd | ||
|
|
4c5cb85c7d | ||
|
|
3bd44d69ca | ||
|
|
d72dd006ad | ||
|
|
6506e03bcf | ||
|
|
443628827e | ||
|
|
85261361d7 | ||
|
|
d91e3bf56d | ||
|
|
d4cad47d09 | ||
|
|
a2f8ea2bea | ||
|
|
89239314d2 | ||
|
|
c5b1f5b019 | ||
|
|
68568c1961 | ||
|
|
34a07a15e2 | ||
|
|
f524df8e4e | ||
|
|
71781d8468 | ||
|
|
c9b9040747 | ||
|
|
b4312e3395 | ||
|
|
21b8599be5 | ||
|
|
a8539b33db | ||
|
|
5d983b082e | ||
|
|
188b9c112c | ||
|
|
6c4a743200 | ||
|
|
e00ee5cdc9 | ||
|
|
b1680e65c9 | ||
|
|
aee83fb113 | ||
|
|
e556ccc7ed | ||
|
|
6b7aa4fc78 | ||
|
|
529b7ae12a | ||
|
|
a18479da64 | ||
|
|
65a72c65ed | ||
|
|
8d19948f4b | ||
|
|
14dbd35b52 | ||
|
|
cacc290e7b | ||
|
|
8f37502c80 | ||
|
|
182951a0d5 | ||
|
|
0783016676 | ||
|
|
4fbf3d14ae | ||
|
|
c36743de83 | ||
|
|
297f8950b1 | ||
|
|
849642ff84 | ||
|
|
dff3b91bef | ||
|
|
7db58f7d16 | ||
|
|
e820a484d6 | ||
|
|
fd702085f5 | ||
|
|
2afba0977f | ||
|
|
30c7556339 | ||
|
|
61d2f956e3 | ||
|
|
b40abd805f | ||
|
|
17b9002fef | ||
|
|
2bab1f468b | ||
|
|
57d4adcb71 | ||
|
|
3a69892446 | ||
|
|
d6f375490a | ||
|
|
bee39ec1bf | ||
|
|
a48c47a669 | ||
|
|
3bbec714a7 | ||
|
|
0dc755518c | ||
|
|
e67361f821 | ||
|
|
27b42c45d7 | ||
|
|
ad3f2cb53a | ||
|
|
76638be446 | ||
|
|
74f9fd4f9d | ||
|
|
c69a3eed70 | ||
|
|
0c12ec9132 | ||
|
|
2f6f0a0f05 | ||
|
|
c0174be906 | ||
|
|
7e96ed15f2 | ||
|
|
9da98fd58b | ||
|
|
1b07143fde | ||
|
|
ea31d78891 | ||
|
|
492731632c | ||
|
|
551fecde83 | ||
|
|
04769a1b48 | ||
|
|
74a1d2acf3 | ||
|
|
aed8d19aea | ||
|
|
de854d492a | ||
|
|
8d3f87c87c | ||
|
|
ff6b50d0a8 | ||
|
|
c669868b36 | ||
|
|
3cb98b70ce | ||
|
|
f2ec43b318 | ||
|
|
d1ffc8d72e | ||
|
|
8028878d1c | ||
|
|
49f88c4e7c | ||
|
|
41ac1e7b89 | ||
|
|
41f69f51f3 | ||
|
|
53bffa7f04 | ||
|
|
8e1ada2b3d | ||
|
|
4122aadb73 | ||
|
|
92c0c7d503 | ||
|
|
34b1a07124 | ||
|
|
ae637ab3e5 | ||
|
|
83c8cb0ef7 | ||
|
|
2cd7e41c05 | ||
|
|
cf95248c37 | ||
|
|
8cc0622598 | ||
|
|
64e2832011 | ||
|
|
65ae8458b1 | ||
|
|
b904eaa886 | ||
|
|
9d7c1890e1 | ||
|
|
48e1618cdd | ||
|
|
3455489f47 | ||
|
|
af919cac66 | ||
|
|
ead46658c0 | ||
|
|
732f7d40ea | ||
|
|
67444a07c2 | ||
|
|
a6da307048 | ||
|
|
55dabe8e6b | ||
|
|
7e82a47dd3 | ||
|
|
c56e4a35d5 | ||
|
|
02f3bb8bba | ||
|
|
a4fc71a5b1 | ||
|
|
a33387faa6 | ||
|
|
ec087d0747 | ||
|
|
23659f8aea | ||
|
|
b51a15c3f2 | ||
|
|
dc30eb2073 | ||
|
|
c6b8873f0c | ||
|
|
78cce48aa1 | ||
|
|
73c40cf561 | ||
|
|
a10d7b69d4 | ||
|
|
4164297a89 | ||
|
|
56534dba1c | ||
|
|
f50e3d60a9 | ||
|
|
e31d478c11 | ||
|
|
0fa901f6bc | ||
|
|
23366ac178 | ||
|
|
6fc234494a | ||
|
|
fdbbc6b7e7 | ||
|
|
67fd109d68 | ||
|
|
3ecf5a7420 | ||
|
|
69f4c901a9 | ||
|
|
3130493a3c | ||
|
|
87529e0994 | ||
|
|
e8816398a8 | ||
|
|
bb1269d635 | ||
|
|
38cec4e35d | ||
|
|
2b5d246725 | ||
|
|
9b2405f3eb | ||
|
|
4ca1901417 | ||
|
|
2208011dd3 | ||
|
|
9a2b254d0c | ||
|
|
9103d95ebc | ||
|
|
d74b319b44 | ||
|
|
3d3d528e02 | ||
|
|
28326b506b | ||
|
|
392565f395 | ||
|
|
532a95e783 | ||
|
|
5d09760b94 | ||
|
|
ac60c28baa | ||
|
|
40ec6066c1 | ||
|
|
d0c5bede65 | ||
|
|
bd6005e23d | ||
|
|
e8ff2ebaf8 | ||
|
|
24f5e0b043 | ||
|
|
8eb843c951 | ||
|
|
543ab09012 | ||
|
|
7389f25f1c | ||
|
|
ac9f021b92 | ||
|
|
b0b5459adb | ||
|
|
669ce753b2 | ||
|
|
a7655046b9 | ||
|
|
7dbac954d1 | ||
|
|
828bc82363 | ||
|
|
e8b50d80ed | ||
|
|
181d210aa5 | ||
|
|
6e487520ed | ||
|
|
6e4334ac52 | ||
|
|
924c889c31 | ||
|
|
d4db93a86a | ||
|
|
4953b3ccdc | ||
|
|
438d3f9b0e | ||
|
|
d5de0fc55c | ||
|
|
9c24024bc9 | ||
|
|
388faaa8e5 | ||
|
|
b386a78dae | ||
|
|
0ea0472b4f | ||
|
|
af8978a886 | ||
|
|
6d74bebf66 | ||
|
|
a99b5d66ca | ||
|
|
3c9de171c7 | ||
|
|
b0e694601e | ||
|
|
0e90beeb01 | ||
|
|
e160395978 | ||
|
|
46c25b38d7 | ||
|
|
455c60c15c | ||
|
|
00b419be94 | ||
|
|
df33d0bd07 | ||
|
|
df37357316 | ||
|
|
9d40b5dc4e | ||
|
|
ec28a40f90 | ||
|
|
b8fb056981 | ||
|
|
b0ace4774e | ||
|
|
34c96c99cf | ||
|
|
54bd12c7c2 | ||
|
|
f29ea94f6e | ||
|
|
5741326cb5 | ||
|
|
609c66c2f0 | ||
|
|
58643b0aae | ||
|
|
d20f70a0c3 | ||
|
|
c24e7e05bf | ||
|
|
fd710d8a7d | ||
|
|
b6814e1133 | ||
|
|
62deb59314 | ||
|
|
925f460d64 | ||
|
|
232bff2041 | ||
|
|
e9b1dcd2fd | ||
|
|
42a8855370 | ||
|
|
6c2359a0ca | ||
|
|
3770d6c14f | ||
|
|
571d1b7bb7 | ||
|
|
b975b31d97 | ||
|
|
c01d9e6b59 | ||
|
|
609b4f5838 | ||
|
|
23e1c36462 | ||
|
|
4d765b37bb | ||
|
|
e0d8cc5469 | ||
|
|
e606cc527e | ||
|
|
4403e1c8ff | ||
|
|
fbb59f8d0a | ||
|
|
0b0f5d2334 | ||
|
|
25cd7a5810 | ||
|
|
7aab07365d | ||
|
|
6acaa9be8b | ||
|
|
11a9819e3b | ||
|
|
4997b69433 | ||
|
|
e2f1f368b5 | ||
|
|
7ea5c3a32f | ||
|
|
bd46dc4233 | ||
|
|
03b1e326ce | ||
|
|
7449915919 | ||
|
|
0e66862cbb | ||
|
|
df8083fb23 | ||
|
|
ee9c704a4c | ||
|
|
105f8d85b3 | ||
|
|
cc6ec1572b | ||
|
|
37d39617bf | ||
|
|
3c92af4a06 | ||
|
|
e3993945eb | ||
|
|
71e1e06faf | ||
|
|
6d77a2e25a | ||
|
|
eff47e0464 | ||
|
|
70aadd2280 | ||
|
|
f7cb82abb5 | ||
|
|
743f6079a1 | ||
|
|
fb9f72d17b | ||
|
|
bb56c8a98c | ||
|
|
c1771dce56 | ||
|
|
88b71f05fa | ||
|
|
52e4f5ea59 | ||
|
|
77b8965e29 | ||
|
|
0791a02223 | ||
|
|
8fdc6f0898 | ||
|
|
3d5484e410 | ||
|
|
d289dabfff | ||
|
|
9f766ff4cd | ||
|
|
ed46ed8ca8 | ||
|
|
87001cd4fe | ||
|
|
88d4de73c2 | ||
|
|
435e94c3f5 | ||
|
|
53ede01f5e | ||
|
|
62363587e0 | ||
|
|
b6f32d1044 | ||
|
|
2b241232da | ||
|
|
5824f38184 | ||
|
|
b0f43cef69 | ||
|
|
1cf6375ae6 | ||
|
|
8c4d6a55a7 | ||
|
|
c8e9ad92a9 | ||
|
|
805818941c | ||
|
|
b0335afd69 | ||
|
|
33b84b15e1 | ||
|
|
273626208b | ||
|
|
1026bee78d | ||
|
|
20e04bf8e6 | ||
|
|
589bf3868d | ||
|
|
50be967c05 | ||
|
|
5ecd0842ce | ||
|
|
38b8182259 | ||
|
|
e460b94b90 | ||
|
|
7c6be558f9 | ||
|
|
4f316bd4b4 | ||
|
|
cdaf03ce09 | ||
|
|
74f769d8dd | ||
|
|
b3e4ced142 | ||
|
|
e219783d40 | ||
|
|
ed56c5c1f2 | ||
|
|
3659a9206a | ||
|
|
91ce95babe | ||
|
|
0bab3451b5 | ||
|
|
d25103ebdb | ||
|
|
af99c1b403 | ||
|
|
5eb8ceadf2 | ||
|
|
7bca5019f6 | ||
|
|
129e4618ea | ||
|
|
703b4ce577 | ||
|
|
74eee18701 | ||
|
|
25aca6b548 | ||
|
|
0ad43e1018 | ||
|
|
ec92f48c76 | ||
|
|
cfdaf345e3 | ||
|
|
b0e4250a4b | ||
|
|
3892a3a711 | ||
|
|
438f7360c7 | ||
|
|
3ad07748b2 | ||
|
|
1540329624 | ||
|
|
ffc2dc804c | ||
|
|
78adf15eea | ||
|
|
5264f3fa26 | ||
|
|
5edbf114a6 | ||
|
|
63d07cc5fd | ||
|
|
a09a55eea7 | ||
|
|
9f5f246209 | ||
|
|
71f9aa5c5b | ||
|
|
12f1476974 | ||
|
|
f33895af6d | ||
|
|
195cd3e049 | ||
|
|
6859b7a835 | ||
|
|
b5cf29437f | ||
|
|
427a9721c2 | ||
|
|
463f4d2e24 | ||
|
|
a69c57ab4a | ||
|
|
027c150ef2 | ||
|
|
4ee2ff7199 | ||
|
|
8ac4137f0d | ||
|
|
a55470b3d4 | ||
|
|
259c18c978 | ||
|
|
bdb56b7bd7 | ||
|
|
b3ba26d5f0 | ||
|
|
f8cbbe792c | ||
|
|
bc4dfc6b5b | ||
|
|
abc5f7d9d5 | ||
|
|
bcf05e8d03 | ||
|
|
6e067e8d33 | ||
|
|
458141774a | ||
|
|
a7ec36fa3a | ||
|
|
ace1ef7ebe | ||
|
|
afc62da1fe | ||
|
|
3dbcf46d0e | ||
|
|
30a62d8fb9 | ||
|
|
adcaa71b68 | ||
|
|
ca1b770c0b | ||
|
|
bb800f657e | ||
|
|
a256e3b8c1 | ||
|
|
296ee76e72 | ||
|
|
c347facba3 | ||
|
|
9287f446dd | ||
|
|
3ef01f79db | ||
|
|
0f7c64325e | ||
|
|
6cb1ec0fa1 | ||
|
|
3bde761e32 | ||
|
|
1759febe5d | ||
|
|
07cfc17797 | ||
|
|
01171fb1b0 | ||
|
|
12583fd0c2 | ||
|
|
c8c4dbd050 | ||
|
|
2b496ca8af | ||
|
|
6e799423d5 | ||
|
|
3f15569518 | ||
|
|
0245ba753e | ||
|
|
9e9cf7964e | ||
|
|
9c071517b7 |
+13
-8
@@ -1,25 +1,30 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: springcloud/pipeline-base
|
||||
user: appuser
|
||||
machine:
|
||||
image: "ubuntu-2004:202201-02"
|
||||
environment:
|
||||
_JAVA_OPTIONS: "-Xms1024m -Xmx2048m"
|
||||
TERM: dumb
|
||||
branches:
|
||||
ignore:
|
||||
- gh-pages # list of branches to ignore
|
||||
resource_class: large
|
||||
steps:
|
||||
- run:
|
||||
name: Install OpenJDK 17
|
||||
command: |
|
||||
wget -qO - https://adoptium.jfrog.io/adoptium/api/gpg/key/public | sudo apt-key add -
|
||||
sudo add-apt-repository --yes https://adoptium.jfrog.io/adoptium/deb/
|
||||
sudo apt-get update && sudo apt-get install temurin-17-jdk
|
||||
sudo update-alternatives --set java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java
|
||||
sudo update-alternatives --set javac /usr/lib/jvm/temurin-17-jdk-amd64/bin/javac
|
||||
java -version
|
||||
- checkout
|
||||
- restore_cache:
|
||||
key: sc-netflix-{{ .Branch }}
|
||||
- run:
|
||||
name: "Download dependencies"
|
||||
command: |
|
||||
cd spring-cloud-netflix-hystrix-contract && ../mvnw clean install && \
|
||||
./mvnw -s .settings.xml -U --fail-never dependency:go-offline || true
|
||||
command: ./mvnw -s .settings.xml -U --fail-never dependency:go-offline || true
|
||||
- save_cache:
|
||||
key: sc-netflix-{{ .Branch }}
|
||||
paths:
|
||||
@@ -39,4 +44,4 @@ jobs:
|
||||
destination: artifacts
|
||||
- store_test_results:
|
||||
path: ~/junit/
|
||||
destination: testartifacts
|
||||
destination: testartifacts
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
root=true
|
||||
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
continuation_indent_size = 8
|
||||
|
||||
[*.groovy]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
continuation_indent_size = 8
|
||||
|
||||
[*.xml]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
continuation_indent_size = 8
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Spring Cloud is released under the non-restrictive Apache 2.0 license,
|
||||
and follows a very standard Github development process, using Github
|
||||
tracker for issues and merging pull requests into master. If you want
|
||||
tracker for issues and merging pull requests into main. If you want
|
||||
to contribute even something trivial please do not hesitate, but
|
||||
follow the guidelines below.
|
||||
|
||||
@@ -17,7 +17,7 @@ given the ability to merge pull requests.
|
||||
|
||||
## Code of Conduct
|
||||
This project adheres to the Contributor Covenant [code of
|
||||
conduct](https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
|
||||
conduct](https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/src/main/asciidoc/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
|
||||
unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
## Code Conventions and Housekeeping
|
||||
@@ -27,7 +27,7 @@ added after the original pull request but before a merge.
|
||||
* Use the Spring Framework code format conventions. If you use Eclipse
|
||||
you can import formatter settings using the
|
||||
`eclipse-code-formatter.xml` file from the
|
||||
[Spring Cloud Build](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml) project. If using IntelliJ, you can use the
|
||||
[Spring Cloud Build](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/spring-cloud-dependencies-parent/eclipse-code-formatter.xml) project. If using IntelliJ, you can use the
|
||||
[Eclipse Code Formatter Plugin](https://plugins.jetbrains.com/plugin/6546) to import the same file.
|
||||
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
|
||||
`@author` tag identifying you, and preferably at least a paragraph on what the class is
|
||||
@@ -38,7 +38,7 @@ added after the original pull request but before a merge.
|
||||
than cosmetic changes).
|
||||
* Add some Javadocs and, if you change the namespace, some XSD doc elements.
|
||||
* A few unit tests would help a lot as well -- someone has to do it.
|
||||
* If no-one else is using your branch, please rebase it against the current master (or
|
||||
* If no-one else is using your branch, please rebase it against the current main (or
|
||||
other target branch in the main project).
|
||||
* When writing a commit message please follow [these conventions](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
|
||||
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: waiting-for-triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
Please provide details of the problem, including the version of Spring Cloud that you
|
||||
are using.
|
||||
|
||||
**Sample**
|
||||
If possible, please provide a test case or sample application that reproduces
|
||||
the problem. This makes it much easier for us to diagnose the problem and to verify that
|
||||
we have fixed it.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -18,3 +18,5 @@ _site/
|
||||
.shelf
|
||||
*.swp
|
||||
*.swo
|
||||
.vscode/
|
||||
.flattened-pom.xml
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenWrapperDownloader {
|
||||
|
||||
/**
|
||||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
|
||||
*/
|
||||
private static final String DEFAULT_DOWNLOAD_URL =
|
||||
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar";
|
||||
|
||||
/**
|
||||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
|
||||
* use instead of the default one.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
|
||||
".mvn/wrapper/maven-wrapper.properties";
|
||||
|
||||
/**
|
||||
* Path where the maven-wrapper.jar will be saved to.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_JAR_PATH =
|
||||
".mvn/wrapper/maven-wrapper.jar";
|
||||
|
||||
/**
|
||||
* Name of the property which should be used to override the default download url for the wrapper.
|
||||
*/
|
||||
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("- Downloader started");
|
||||
File baseDirectory = new File(args[0]);
|
||||
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
|
||||
|
||||
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
||||
// wrapperUrl parameter.
|
||||
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
|
||||
String url = DEFAULT_DOWNLOAD_URL;
|
||||
if(mavenWrapperPropertyFile.exists()) {
|
||||
FileInputStream mavenWrapperPropertyFileInputStream = null;
|
||||
try {
|
||||
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
|
||||
Properties mavenWrapperProperties = new Properties();
|
||||
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
|
||||
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
|
||||
} catch (IOException e) {
|
||||
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
|
||||
} finally {
|
||||
try {
|
||||
if(mavenWrapperPropertyFileInputStream != null) {
|
||||
mavenWrapperPropertyFileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore ...
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading from: : " + url);
|
||||
|
||||
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
|
||||
if(!outputFile.getParentFile().exists()) {
|
||||
if(!outputFile.getParentFile().mkdirs()) {
|
||||
System.out.println(
|
||||
"- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
|
||||
try {
|
||||
downloadFileFromURL(url, outputFile);
|
||||
System.out.println("Done");
|
||||
System.exit(0);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("- Error downloading");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
|
||||
URL website = new URL(urlString);
|
||||
ReadableByteChannel rbc;
|
||||
rbc = Channels.newChannel(website.openStream());
|
||||
FileOutputStream fos = new FileOutputStream(destination);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
fos.close();
|
||||
rbc.close();
|
||||
}
|
||||
|
||||
}
|
||||
BIN
Binary file not shown.
+1
-1
@@ -1 +1 @@
|
||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip
|
||||
@@ -0,0 +1,3 @@
|
||||
# Enable auto-env through the sdkman_auto_env config
|
||||
# Add key=value pairs of SDKs to use below
|
||||
java=17.0.1-tem
|
||||
@@ -1,11 +0,0 @@
|
||||
require 'asciidoctor'
|
||||
require 'erb'
|
||||
|
||||
options = {:mkdirs => true, :safe => :unsafe, :attributes => ['linkcss', 'allow-uri-read']}
|
||||
|
||||
guard 'shell' do
|
||||
watch(/^docs\/[A-Z-a-z][^#]*\.adoc$/) {|m|
|
||||
Asciidoctor.load_file('docs/src/main/asciidoc/README.adoc', :to_file => './README.adoc', safe: :safe, parse: false, attributes: 'allow-uri-read')
|
||||
Asciidoctor.render_file('docs/src/main/asciidoc/spring-cloud-netflix.adoc', options.merge(:to_dir => 'target/generated-docs'))
|
||||
}
|
||||
end
|
||||
+245
-29
@@ -1,31 +1,63 @@
|
||||
// Do not edit this file (e.g. go instead to src/main/asciidoc)
|
||||
////
|
||||
DO NOT EDIT THIS FILE. IT WAS GENERATED.
|
||||
Manual changes to this file will be lost when it is generated again.
|
||||
Edit the files in the src/main/asciidoc/ directory instead.
|
||||
////
|
||||
|
||||
image::https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master"]
|
||||
image::https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master"]
|
||||
image::https://api.codacy.com/project/badge/Grade/a6885a06921e4f72a0df0b7aabd6d118["Codacy code quality", link="https://www.codacy.com/app/Spring-Cloud/spring-cloud-netflix?utm_source=github.com&utm_medium=referral&utm_content=spring-cloud/spring-cloud-netflix&utm_campaign=Badge_Grade"]
|
||||
|
||||
:doctype: book
|
||||
:idprefix:
|
||||
:idseparator: -
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:numbered:
|
||||
:sectanchors:
|
||||
:sectnums:
|
||||
:icons: font
|
||||
:hide-uri-scheme:
|
||||
:docinfo: shared,private
|
||||
|
||||
:sc-ext: java
|
||||
:project-full-name: Spring Cloud Netflix
|
||||
|
||||
image::https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/main.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/main"]
|
||||
image::https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/main/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/main"]
|
||||
|
||||
|
||||
:doctype: book
|
||||
:idprefix:
|
||||
:idseparator: -
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:numbered:
|
||||
:sectanchors:
|
||||
:sectnums:
|
||||
:icons: font
|
||||
:hide-uri-scheme:
|
||||
:docinfo: shared,private
|
||||
|
||||
:sc-ext: java
|
||||
:project-full-name: Spring Cloud Netflix
|
||||
|
||||
This project provides Netflix OSS integrations for Spring Boot apps through autoconfiguration
|
||||
and binding to the Spring Environment and other Spring programming model idioms. With a few
|
||||
simple annotations you can quickly enable and configure the common patterns inside your
|
||||
application and build large distributed systems with battle-tested Netflix components. The
|
||||
patterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix),
|
||||
Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).
|
||||
patterns provided include Service Discovery (Eureka).
|
||||
|
||||
|
||||
== Features
|
||||
|
||||
* Service Discovery: Eureka instances can be registered and clients can discover the instances using Spring-managed beans
|
||||
* Service Discovery: an embedded Eureka server can be created with declarative Java configuration
|
||||
* Circuit Breaker: Hystrix clients can be built with a simple annotation-driven method decorator
|
||||
* Circuit Breaker: embedded Hystrix dashboard with declarative Java configuration
|
||||
* Client Side Load Balancer: Ribbon
|
||||
* External Configuration: a bridge from the Spring Environment to Archaius (enables native configuration of Netflix components using Spring Boot conventions)
|
||||
* Router and Filter: automatic registration of Zuul filters, and a simple convention over configuration approach to reverse proxy creation
|
||||
|
||||
|
||||
== Building
|
||||
|
||||
:jdkversion: 1.8
|
||||
|
||||
:jdkversion: 17
|
||||
|
||||
=== Basic Compile and Test
|
||||
|
||||
@@ -51,23 +83,9 @@ the `.mvn` configuration, so if you find you have to do it to make a
|
||||
build succeed, please raise a ticket to get the settings added to
|
||||
source control.
|
||||
|
||||
For hints on how to build the project look in `.travis.yml` if there
|
||||
is one. There should be a "script" and maybe "install" command. Also
|
||||
look at the "services" section to see if any services need to be
|
||||
running locally (e.g. mongo or rabbit). Ignore the git-related bits
|
||||
that you might find in "before_install" since they're related to setting git
|
||||
credentials and you already have those.
|
||||
The projects that require middleware (i.e. Redis) for testing generally
|
||||
require that a local instance of [Docker](https://www.docker.com/get-started) is installed and running.
|
||||
|
||||
The projects that require middleware generally include a
|
||||
`docker-compose.yml`, so consider using
|
||||
https://compose.docker.io/[Docker Compose] to run the middeware servers
|
||||
in Docker containers. See the README in the
|
||||
https://github.com/spring-cloud-samples/scripts[scripts demo
|
||||
repository] for specific instructions about the common cases of mongo,
|
||||
rabbit and redis.
|
||||
|
||||
NOTE: If all else fails, build with the command from `.travis.yml` (usually
|
||||
`./mvnw install`).
|
||||
|
||||
=== Documentation
|
||||
|
||||
@@ -87,6 +105,11 @@ https://eclipse.org[Eclipse] when working with the code. We use the
|
||||
https://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools
|
||||
should also work without issue as long as they use Maven 3.3.3 or better.
|
||||
|
||||
==== Activate the Spring Maven profile
|
||||
Spring Cloud projects require the 'spring' Maven profile to be activated to resolve
|
||||
the spring milestone and snapshot repositories. Use your preferred IDE to set this
|
||||
profile to be active, or you may experience build errors.
|
||||
|
||||
==== Importing into eclipse with m2eclipse
|
||||
We recommend the https://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with
|
||||
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
|
||||
@@ -115,8 +138,13 @@ from the `file` menu.
|
||||
|
||||
|
||||
|
||||
NOTE: To build the module `spring-cloud-netflix-hystrix-contract` along with the entire Netflix project run the
|
||||
`build.sh` script in the `scripts` directory.
|
||||
|
||||
== Contributing
|
||||
|
||||
:spring-cloud-build-branch: master
|
||||
|
||||
Spring Cloud is released under the non-restrictive Apache 2.0 license,
|
||||
and follows a very standard Github development process, using Github
|
||||
tracker for issues and merging pull requests into master. If you want
|
||||
@@ -160,4 +188,192 @@ added after the original pull request but before a merge.
|
||||
other target branch in the main project).
|
||||
* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
|
||||
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
|
||||
message (where XXXX is the issue number).
|
||||
message (where XXXX is the issue number).
|
||||
|
||||
=== Checkstyle
|
||||
|
||||
Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are:
|
||||
|
||||
.spring-cloud-build-tools/
|
||||
----
|
||||
└── src
|
||||
├── checkstyle
|
||||
│ └── checkstyle-suppressions.xml <3>
|
||||
└── main
|
||||
└── resources
|
||||
├── checkstyle-header.txt <2>
|
||||
└── checkstyle.xml <1>
|
||||
----
|
||||
<1> Default Checkstyle rules
|
||||
<2> File header setup
|
||||
<3> Default suppression rules
|
||||
|
||||
==== Checkstyle configuration
|
||||
|
||||
Checkstyle rules are *disabled by default*. To add checkstyle to your project just define the following properties and plugins.
|
||||
|
||||
.pom.xml
|
||||
----
|
||||
<properties>
|
||||
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> <1>
|
||||
<maven-checkstyle-plugin.failsOnViolation>true
|
||||
</maven-checkstyle-plugin.failsOnViolation> <2>
|
||||
<maven-checkstyle-plugin.includeTestSourceDirectory>true
|
||||
</maven-checkstyle-plugin.includeTestSourceDirectory> <3>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin> <4>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin> <5>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin> <5>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
</build>
|
||||
----
|
||||
<1> Fails the build upon Checkstyle errors
|
||||
<2> Fails the build upon Checkstyle violations
|
||||
<3> Checkstyle analyzes also the test sources
|
||||
<4> Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules
|
||||
<5> Add checkstyle plugin to your build and reporting phases
|
||||
|
||||
If you need to suppress some rules (e.g. line length needs to be longer), then it's enough for you to define a file under `${project.root}/src/checkstyle/checkstyle-suppressions.xml` with your suppressions. Example:
|
||||
|
||||
.projectRoot/src/checkstyle/checkstyle-suppresions.xml
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
|
||||
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
|
||||
<suppressions>
|
||||
<suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/>
|
||||
<suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/>
|
||||
</suppressions>
|
||||
----
|
||||
|
||||
It's advisable to copy the `${spring-cloud-build.rootFolder}/.editorconfig` and `${spring-cloud-build.rootFolder}/.springformat` to your project. That way, some default formatting rules will be applied. You can do so by running this script:
|
||||
|
||||
```bash
|
||||
$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig
|
||||
$ touch .springformat
|
||||
```
|
||||
|
||||
=== IDE setup
|
||||
|
||||
==== Intellij IDEA
|
||||
|
||||
In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin.
|
||||
The following files can be found in the https://github.com/spring-cloud/spring-cloud-build/tree/master/spring-cloud-build-tools[Spring Cloud Build] project.
|
||||
|
||||
.spring-cloud-build-tools/
|
||||
----
|
||||
└── src
|
||||
├── checkstyle
|
||||
│ └── checkstyle-suppressions.xml <3>
|
||||
└── main
|
||||
└── resources
|
||||
├── checkstyle-header.txt <2>
|
||||
├── checkstyle.xml <1>
|
||||
└── intellij
|
||||
├── Intellij_Project_Defaults.xml <4>
|
||||
└── Intellij_Spring_Boot_Java_Conventions.xml <5>
|
||||
----
|
||||
<1> Default Checkstyle rules
|
||||
<2> File header setup
|
||||
<3> Default suppression rules
|
||||
<4> Project defaults for Intellij that apply most of Checkstyle rules
|
||||
<5> Project style conventions for Intellij that apply most of Checkstyle rules
|
||||
|
||||
.Code style
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-code-style.png[Code style]
|
||||
|
||||
Go to `File` -> `Settings` -> `Editor` -> `Code style`. There click on the icon next to the `Scheme` section. There, click on the `Import Scheme` value and pick the `Intellij IDEA code style XML` option. Import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml` file.
|
||||
|
||||
.Inspection profiles
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-inspections.png[Code style]
|
||||
|
||||
Go to `File` -> `Settings` -> `Editor` -> `Inspections`. There click on the icon next to the `Profile` section. There, click on the `Import Profile` and import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml` file.
|
||||
|
||||
.Checkstyle
|
||||
|
||||
To have Intellij work with Checkstyle, you have to install the `Checkstyle` plugin. It's advisable to also install the `Assertions2Assertj` to automatically convert the JUnit assertions
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-checkstyle.png[Checkstyle]
|
||||
|
||||
Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on the `+` icon in the `Configuration file` section. There, you'll have to define where the checkstyle rules should be picked from. In the image above, we've picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build's GitHub repository (e.g. for the `checkstyle.xml` : `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml`). We need to provide the following variables:
|
||||
|
||||
- `checkstyle.header.file` - please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` URL.
|
||||
- `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL.
|
||||
- `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`.
|
||||
|
||||
IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources.
|
||||
|
||||
=== Duplicate Finder
|
||||
|
||||
Spring Cloud Build brings along the `basepom:duplicate-finder-maven-plugin`, that enables flagging duplicate and conflicting classes and resources on the java classpath.
|
||||
|
||||
==== Duplicate Finder configuration
|
||||
|
||||
Duplicate finder is *enabled by default* and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the projecst's `pom.xml`.
|
||||
|
||||
.pom.xml
|
||||
[source,xml]
|
||||
----
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.basepom.maven</groupId>
|
||||
<artifactId>duplicate-finder-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
----
|
||||
|
||||
For other properties, we have set defaults as listed in the https://github.com/basepom/duplicate-finder-maven-plugin/wiki[plugin documentation].
|
||||
|
||||
You can easily override them but setting the value of the selected property prefixed with `duplicate-finder-maven-plugin`. For example, set `duplicate-finder-maven-plugin.skip` to `true` in order to skip duplicates check in your build.
|
||||
|
||||
If you need to add `ignoredClassPatterns` or `ignoredResourcePatterns` to your setup, make sure to add them in the plugin configuration section of your project:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.basepom.maven</groupId>
|
||||
<artifactId>duplicate-finder-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<ignoredClassPatterns>
|
||||
<ignoredClassPattern>org.joda.time.base.BaseDateTime</ignoredClassPattern>
|
||||
<ignoredClassPattern>.*module-info</ignoredClassPattern>
|
||||
</ignoredClassPatterns>
|
||||
<ignoredResourcePatterns>
|
||||
<ignoredResourcePattern>changelog.txt</ignoredResourcePattern>
|
||||
</ignoredResourcePatterns>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
== License
|
||||
|
||||
The project license file is available https://raw.githubusercontent.com/spring-cloud/spring-cloud-netflix/main/LICENSE.txt[here].
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
releaser:
|
||||
maven:
|
||||
buildCommand: ./scripts/build.sh {{systemProps}}
|
||||
@@ -1,297 +0,0 @@
|
||||
// Do not edit this file (e.g. go instead to src/main/asciidoc)
|
||||
|
||||
image::https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master"]
|
||||
image::https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master"]
|
||||
image::https://api.codacy.com/project/badge/Grade/a6885a06921e4f72a0df0b7aabd6d118["Codacy code quality", link="https://www.codacy.com/app/Spring-Cloud/spring-cloud-netflix?utm_source=github.com&utm_medium=referral&utm_content=spring-cloud/spring-cloud-netflix&utm_campaign=Badge_Grade"]
|
||||
|
||||
|
||||
This project provides Netflix OSS integrations for Spring Boot apps through autoconfiguration
|
||||
and binding to the Spring Environment and other Spring programming model idioms. With a few
|
||||
simple annotations you can quickly enable and configure the common patterns inside your
|
||||
application and build large distributed systems with battle-tested Netflix components. The
|
||||
patterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix),
|
||||
Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).
|
||||
|
||||
|
||||
== Features
|
||||
|
||||
* Service Discovery: Eureka instances can be registered and clients can discover the instances using Spring-managed beans
|
||||
* Service Discovery: an embedded Eureka server can be created with declarative Java configuration
|
||||
* Circuit Breaker: Hystrix clients can be built with a simple annotation-driven method decorator
|
||||
* Circuit Breaker: embedded Hystrix dashboard with declarative Java configuration
|
||||
* Client Side Load Balancer: Ribbon
|
||||
* External Configuration: a bridge from the Spring Environment to Archaius (enables native configuration of Netflix components using Spring Boot conventions)
|
||||
* Router and Filter: automatic registration of Zuul filters, and a simple convention over configuration approach to reverse proxy creation
|
||||
|
||||
== Building
|
||||
|
||||
:jdkversion: 1.8
|
||||
|
||||
=== Basic Compile and Test
|
||||
|
||||
To build the source you will need to install JDK {jdkversion}.
|
||||
|
||||
Spring Cloud uses Maven for most build-related activities, and you
|
||||
should be able to get off the ground quite quickly by cloning the
|
||||
project you are interested in and typing
|
||||
|
||||
----
|
||||
$ ./mvnw install
|
||||
----
|
||||
|
||||
NOTE: You can also install Maven (>=3.3.3) yourself and run the `mvn` command
|
||||
in place of `./mvnw` in the examples below. If you do that you also
|
||||
might need to add `-P spring` if your local Maven settings do not
|
||||
contain repository declarations for spring pre-release artifacts.
|
||||
|
||||
NOTE: Be aware that you might need to increase the amount of memory
|
||||
available to Maven by setting a `MAVEN_OPTS` environment variable with
|
||||
a value like `-Xmx512m -XX:MaxPermSize=128m`. We try to cover this in
|
||||
the `.mvn` configuration, so if you find you have to do it to make a
|
||||
build succeed, please raise a ticket to get the settings added to
|
||||
source control.
|
||||
|
||||
For hints on how to build the project look in `.travis.yml` if there
|
||||
is one. There should be a "script" and maybe "install" command. Also
|
||||
look at the "services" section to see if any services need to be
|
||||
running locally (e.g. mongo or rabbit). Ignore the git-related bits
|
||||
that you might find in "before_install" since they're related to setting git
|
||||
credentials and you already have those.
|
||||
|
||||
The projects that require middleware generally include a
|
||||
`docker-compose.yml`, so consider using
|
||||
https://compose.docker.io/[Docker Compose] to run the middeware servers
|
||||
in Docker containers. See the README in the
|
||||
https://github.com/spring-cloud-samples/scripts[scripts demo
|
||||
repository] for specific instructions about the common cases of mongo,
|
||||
rabbit and redis.
|
||||
|
||||
NOTE: If all else fails, build with the command from `.travis.yml` (usually
|
||||
`./mvnw install`).
|
||||
|
||||
=== Documentation
|
||||
|
||||
The spring-cloud-build module has a "docs" profile, and if you switch
|
||||
that on it will try to build asciidoc sources from
|
||||
`src/main/asciidoc`. As part of that process it will look for a
|
||||
`README.adoc` and process it by loading all the includes, but not
|
||||
parsing or rendering it, just copying it to `${main.basedir}`
|
||||
(defaults to `${basedir}`, i.e. the root of the project). If there are
|
||||
any changes in the README it will then show up after a Maven build as
|
||||
a modified file in the correct place. Just commit it and push the change.
|
||||
|
||||
=== Working with the code
|
||||
If you don't have an IDE preference we would recommend that you use
|
||||
https://www.springsource.com/developer/sts[Spring Tools Suite] or
|
||||
https://eclipse.org[Eclipse] when working with the code. We use the
|
||||
https://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools
|
||||
should also work without issue as long as they use Maven 3.3.3 or better.
|
||||
|
||||
==== Importing into eclipse with m2eclipse
|
||||
We recommend the https://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with
|
||||
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
|
||||
marketplace".
|
||||
|
||||
NOTE: Older versions of m2e do not support Maven 3.3, so once the
|
||||
projects are imported into Eclipse you will also need to tell
|
||||
m2eclipse to use the right profile for the projects. If you
|
||||
see many different errors related to the POMs in the projects, check
|
||||
that you have an up to date installation. If you can't upgrade m2e,
|
||||
add the "spring" profile to your `settings.xml`. Alternatively you can
|
||||
copy the repository settings from the "spring" profile of the parent
|
||||
pom into your `settings.xml`.
|
||||
|
||||
==== Importing into eclipse without m2eclipse
|
||||
If you prefer not to use m2eclipse you can generate eclipse project metadata using the
|
||||
following command:
|
||||
|
||||
[indent=0]
|
||||
----
|
||||
$ ./mvnw eclipse:eclipse
|
||||
----
|
||||
|
||||
The generated eclipse projects can be imported by selecting `import existing projects`
|
||||
from the `file` menu.
|
||||
|
||||
|
||||
|
||||
== Contributing
|
||||
|
||||
:spring-cloud-build-branch: master
|
||||
|
||||
Spring Cloud is released under the non-restrictive Apache 2.0 license,
|
||||
and follows a very standard Github development process, using Github
|
||||
tracker for issues and merging pull requests into master. If you want
|
||||
to contribute even something trivial please do not hesitate, but
|
||||
follow the guidelines below.
|
||||
|
||||
=== Sign the Contributor License Agreement
|
||||
Before we accept a non-trivial patch or pull request we will need you to sign the
|
||||
https://cla.pivotal.io/sign/spring[Contributor License Agreement].
|
||||
Signing the contributor's agreement does not grant anyone commit rights to the main
|
||||
repository, but it does mean that we can accept your contributions, and you will get an
|
||||
author credit if we do. Active contributors might be asked to join the core team, and
|
||||
given the ability to merge pull requests.
|
||||
|
||||
=== Code of Conduct
|
||||
This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of
|
||||
conduct]. By participating, you are expected to uphold this code. Please report
|
||||
unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
=== Code Conventions and Housekeeping
|
||||
None of these is essential for a pull request, but they will all help. They can also be
|
||||
added after the original pull request but before a merge.
|
||||
|
||||
* Use the Spring Framework code format conventions. If you use Eclipse
|
||||
you can import formatter settings using the
|
||||
`eclipse-code-formatter.xml` file from the
|
||||
https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring
|
||||
Cloud Build] project. If using IntelliJ, you can use the
|
||||
https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
|
||||
Plugin] to import the same file.
|
||||
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
|
||||
`@author` tag identifying you, and preferably at least a paragraph on what the class is
|
||||
for.
|
||||
* Add the ASF license header comment to all new `.java` files (copy from existing files
|
||||
in the project)
|
||||
* Add yourself as an `@author` to the .java files that you modify substantially (more
|
||||
than cosmetic changes).
|
||||
* Add some Javadocs and, if you change the namespace, some XSD doc elements.
|
||||
* A few unit tests would help a lot as well -- someone has to do it.
|
||||
* If no-one else is using your branch, please rebase it against the current master (or
|
||||
other target branch in the main project).
|
||||
* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
|
||||
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
|
||||
message (where XXXX is the issue number).
|
||||
|
||||
=== Checkstyle
|
||||
|
||||
Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are:
|
||||
|
||||
.spring-cloud-build-tools/
|
||||
----
|
||||
└── src
|
||||
├── checkstyle
|
||||
│ └── checkstyle-suppressions.xml <3>
|
||||
└── main
|
||||
└── resources
|
||||
├── checkstyle-header.txt <2>
|
||||
└── checkstyle.xml <1>
|
||||
----
|
||||
<1> Default Checkstyle rules
|
||||
<2> File header setup
|
||||
<3> Default suppression rules
|
||||
|
||||
==== Checkstyle configuration
|
||||
|
||||
Checkstyle rules are *disabled by default*. To add checkstyle to your project just define the following properties and plugins.
|
||||
|
||||
.pom.xml
|
||||
----
|
||||
<properties>
|
||||
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> <1>
|
||||
<maven-checkstyle-plugin.failsOnViolation>true
|
||||
</maven-checkstyle-plugin.failsOnViolation> <2>
|
||||
<maven-checkstyle-plugin.includeTestSourceDirectory>true
|
||||
</maven-checkstyle-plugin.includeTestSourceDirectory> <3>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin> <4>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin> <5>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin> <5>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
</build>
|
||||
----
|
||||
<1> Fails the build upon Checkstyle errors
|
||||
<2> Fails the build upon Checkstyle violations
|
||||
<3> Checkstyle analyzes also the test sources
|
||||
<4> Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules
|
||||
<5> Add checkstyle plugin to your build and reporting phases
|
||||
|
||||
If you need to suppress some rules (e.g. line length needs to be longer), then it's enough for you to define a file under `${project.root}/src/checkstyle/checkstyle-suppressions.xml` with your suppressions. Example:
|
||||
|
||||
.projectRoot/src/checkstyle/checkstyle-suppresions.xml
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
|
||||
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
|
||||
<suppressions>
|
||||
<suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/>
|
||||
<suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/>
|
||||
</suppressions>
|
||||
----
|
||||
|
||||
It's advisable to copy the `${spring-cloud-build.rootFolder}/.editorconfig` and `${spring-cloud-build.rootFolder}/.springformat` to your project. That way, some default formatting rules will be applied. You can do so by running this script:
|
||||
|
||||
```bash
|
||||
$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig
|
||||
$ touch .springformat
|
||||
```
|
||||
|
||||
=== IDE setup
|
||||
|
||||
==== Intellij IDEA
|
||||
|
||||
In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin.
|
||||
|
||||
.spring-cloud-build-tools/
|
||||
----
|
||||
└── src
|
||||
├── checkstyle
|
||||
│ └── checkstyle-suppressions.xml <3>
|
||||
└── main
|
||||
└── resources
|
||||
├── checkstyle-header.txt <2>
|
||||
├── checkstyle.xml <1>
|
||||
└── intellij
|
||||
├── Intellij_Project_Defaults.xml <4>
|
||||
└── Intellij_Spring_Boot_Java_Conventions.xml <5>
|
||||
----
|
||||
<1> Default Checkstyle rules
|
||||
<2> File header setup
|
||||
<3> Default suppression rules
|
||||
<4> Project defaults for Intellij that apply most of Checkstyle rules
|
||||
<5> Project style conventions for Intellij that apply most of Checkstyle rules
|
||||
|
||||
.Code style
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-code-style.png[Code style]
|
||||
|
||||
Go to `File` -> `Settings` -> `Editor` -> `Code style`. There click on the icon next to the `Scheme` section. There, click on the `Import Scheme` value and pick the `Intellij IDEA code style XML` option. Import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml` file.
|
||||
|
||||
.Inspection profiles
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-inspections.png[Code style]
|
||||
|
||||
Go to `File` -> `Settings` -> `Editor` -> `Inspections`. There click on the icon next to the `Profile` section. There, click on the `Import Profile` and import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml` file.
|
||||
|
||||
.Checkstyle
|
||||
|
||||
To have Intellij work with Checkstyle, you have to install the `Checkstyle` plugin. It's advisable to also install the `Assertions2Assertj` to automatically convert the JUnit assertions
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-checkstyle.png[Checkstyle]
|
||||
|
||||
Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on the `+` icon in the `Configuration file` section. There, you'll have to define where the checkstyle rules should be picked from. In the image above, we've picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build's GitHub repository (e.g. for the `checkstyle.xml` : `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml`). We need to provide the following variables:
|
||||
|
||||
- `checkstyle.header.file` - please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/main/resources/checkstyle/checkstyle-header.txt` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` URL.
|
||||
- `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL.
|
||||
- `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`.
|
||||
|
||||
IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources.
|
||||
+32
-22
@@ -5,25 +5,34 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>2.0.4.BUILD-SNAPSHOT</version>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix-docs</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Netflix Docs</name>
|
||||
<description>Spring Cloud Docs</description>
|
||||
<properties>
|
||||
<docs.main>spring-cloud-netflix</docs.main>
|
||||
<docs.whitelisted.branches>1.2.x,1.3.x,1.4.x</docs.whitelisted.branches>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
<configprops.inclusionPattern>
|
||||
.*.eureka.*
|
||||
</configprops.inclusionPattern>
|
||||
<upload-docs-zip.phase>deploy</upload-docs-zip.phase>
|
||||
<!-- Don't upload docs jar to central / repo.spring.io -->
|
||||
<maven-deploy-plugin-default.phase>none</maven-deploy-plugin-default.phase>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<sourceDirectory>src/main/asciidoc</sourceDirectory>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
@@ -31,27 +40,28 @@
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<groupId>pl.project13.maven</groupId>
|
||||
<artifactId>git-commit-id-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.agilejava.docbkx</groupId>
|
||||
<artifactId>docbkx-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
image::https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master"]
|
||||
image::https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master"]
|
||||
image::https://api.codacy.com/project/badge/Grade/a6885a06921e4f72a0df0b7aabd6d118["Codacy code quality", link="https://www.codacy.com/app/Spring-Cloud/spring-cloud-netflix?utm_source=github.com&utm_medium=referral&utm_content=spring-cloud/spring-cloud-netflix&utm_campaign=Badge_Grade"]
|
||||
include::_attributes.adoc[]
|
||||
|
||||
image::https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/main.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/main"]
|
||||
image::https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/main/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/main"]
|
||||
|
||||
|
||||
include::intro.adoc[]
|
||||
@@ -9,16 +10,19 @@ include::intro.adoc[]
|
||||
|
||||
* Service Discovery: Eureka instances can be registered and clients can discover the instances using Spring-managed beans
|
||||
* Service Discovery: an embedded Eureka server can be created with declarative Java configuration
|
||||
* Circuit Breaker: Hystrix clients can be built with a simple annotation-driven method decorator
|
||||
* Circuit Breaker: embedded Hystrix dashboard with declarative Java configuration
|
||||
* Client Side Load Balancer: Ribbon
|
||||
* External Configuration: a bridge from the Spring Environment to Archaius (enables native configuration of Netflix components using Spring Boot conventions)
|
||||
* Router and Filter: automatic registration of Zuul filters, and a simple convention over configuration approach to reverse proxy creation
|
||||
|
||||
|
||||
== Building
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building-jdk8.adoc[]
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/src/main/asciidoc/building-jdk8.adoc[]
|
||||
|
||||
NOTE: To build the module `spring-cloud-netflix-hystrix-contract` along with the entire Netflix project run the
|
||||
`build.sh` script in the `scripts` directory.
|
||||
|
||||
== Contributing
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[]
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/src/main/asciidoc/contributing.adoc[]
|
||||
|
||||
== License
|
||||
|
||||
The project license file is available https://raw.githubusercontent.com/spring-cloud/spring-cloud-netflix/main/LICENSE.txt[here].
|
||||
@@ -0,0 +1,15 @@
|
||||
:doctype: book
|
||||
:idprefix:
|
||||
:idseparator: -
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:numbered:
|
||||
:sectanchors:
|
||||
:sectnums:
|
||||
:icons: font
|
||||
:hide-uri-scheme:
|
||||
:docinfo: shared,private
|
||||
|
||||
:sc-ext: java
|
||||
:project-full-name: Spring Cloud Netflix
|
||||
@@ -0,0 +1,20 @@
|
||||
|===
|
||||
|Name | Default | Description
|
||||
|
||||
|eureka.client.eureka-connection-idle-timeout-seconds | `+++30+++` | Indicates how much time (in seconds) that the HTTP connections to eureka server can stay idle before it can be closed. In the AWS environment, it is recommended that the values is 30 seconds or less, since the firewall cleans up the connection information after a few mins leaving the connection hanging in limbo.
|
||||
|eureka.client.eureka-server-connect-timeout-seconds | `+++5+++` | Indicates how long to wait (in seconds) before a connection to eureka server needs to timeout. Note that the connections in the client are pooled by {@link HttpClient} and this setting affects the actual connection creation and also the wait time to get the connection from the pool.
|
||||
|eureka.client.eureka-server-d-n-s-name | | Gets the DNS name to be queried to get the list of eureka servers.This information is not required if the contract returns the service urls by implementing serviceUrls. The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the eureka client expects the DNS to configured a certain way so that it can fetch changing eureka servers dynamically. The changes are effective at runtime.
|
||||
|eureka.client.eureka-server-port | | Gets the port to be used to construct the service url to contact eureka server when the list of eureka servers come from the DNS.This information is not required if the contract returns the service urls eurekaServerServiceUrls(String). The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the eureka client expects the DNS to configured a certain way so that it can fetch changing eureka servers dynamically. The changes are effective at runtime.
|
||||
|eureka.client.eureka-server-read-timeout-seconds | `+++8+++` | Indicates how long to wait (in seconds) before a read from eureka server needs to timeout.
|
||||
|eureka.client.eureka-server-total-connections | `+++200+++` | Gets the total number of connections that is allowed from eureka client to all eureka servers.
|
||||
|eureka.client.eureka-server-total-connections-per-host | `+++50+++` | Gets the total number of connections that is allowed from eureka client to a eureka server host.
|
||||
|eureka.client.eureka-server-u-r-l-context | | Gets the URL context to be used to construct the service url to contact eureka server when the list of eureka servers come from the DNS. This information is not required if the contract returns the service urls from eurekaServerServiceUrls. The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the eureka client expects the DNS to configured a certain way so that it can fetch changing eureka servers dynamically. The changes are effective at runtime.
|
||||
|eureka.client.eureka-service-url-poll-interval-seconds | `+++0+++` | Indicates how often(in seconds) to poll for changes to eureka server information. Eureka servers could be added or removed and this setting controls how soon the eureka clients should know about it.
|
||||
|eureka.client.prefer-same-zone-eureka | `+++true+++` | Indicates whether or not this instance should try to use the eureka server in the same zone for latency and/or other reason. Ideally eureka clients are configured to talk to servers in the same zone The changes are effective at runtime at the next registry fetch cycle as specified by registryFetchIntervalSeconds
|
||||
|eureka.client.register-with-eureka | `+++true+++` | Indicates whether or not this instance should register its information with eureka server for discovery by others. In some cases, you do not want your instances to be discovered whereas you just want do discover other instances.
|
||||
|eureka.server.peer-eureka-nodes-update-interval-ms | `+++0+++` |
|
||||
|eureka.server.peer-eureka-status-refresh-time-interval-ms | `+++0+++` |
|
||||
|ribbon.eureka.enabled | `+++true+++` | Enables the use of Eureka with Ribbon.
|
||||
|spring.cloud.loadbalancer.eureka.approximate-zone-from-hostname | `+++false+++` | Used to determine whether we should try to get the `zone` value from host name.
|
||||
|
||||
|===
|
||||
@@ -0,0 +1,14 @@
|
||||
:numbered!:
|
||||
[appendix]
|
||||
[[common-application-properties]]
|
||||
== Common application properties
|
||||
|
||||
include::_attributes.adoc[]
|
||||
|
||||
Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches.
|
||||
This appendix provides a list of common {project-full-name} properties and references to the underlying classes that consume them.
|
||||
|
||||
NOTE: Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list.
|
||||
Also, you can define your own properties.
|
||||
|
||||
include::_configprops.adoc[]
|
||||
@@ -1,10 +1,10 @@
|
||||
#!/bin/bash -x
|
||||
ALLOW#!/bin/bash -x
|
||||
|
||||
set -e
|
||||
|
||||
# Set default props like MAVEN_PATH, ROOT_FOLDER etc.
|
||||
function set_default_props() {
|
||||
# The script should be executed from the root folder
|
||||
# The script should be run from the root folder
|
||||
ROOT_FOLDER=`pwd`
|
||||
echo "Current folder is ${ROOT_FOLDER}"
|
||||
|
||||
@@ -39,7 +39,7 @@ function check_if_anything_to_sync() {
|
||||
}
|
||||
|
||||
function retrieve_current_branch() {
|
||||
# Code getting the name of the current branch. For master we want to publish as we did until now
|
||||
# Code getting the name of the current branch. For main we want to publish as we did until now
|
||||
# https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch
|
||||
# If there is a branch already passed will reuse it - otherwise will try to find it
|
||||
CURRENT_BRANCH=${BRANCH}
|
||||
@@ -65,7 +65,7 @@ function build_docs_if_applicable() {
|
||||
}
|
||||
|
||||
# Get the name of the `docs.main` property
|
||||
# Get whitelisted branches - assumes that a `docs` module is available under `docs` profile
|
||||
# Get allow branches - assumes that a `docs` module is available under `docs` profile
|
||||
function retrieve_doc_properties() {
|
||||
MAIN_ADOC_VALUE=$("${MAVEN_PATH}"mvn -q \
|
||||
-Dexec.executable="echo" \
|
||||
@@ -75,14 +75,14 @@ function retrieve_doc_properties() {
|
||||
echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]"
|
||||
|
||||
|
||||
WHITELIST_PROPERTY=${WHITELIST_PROPERTY:-"docs.whitelisted.branches"}
|
||||
WHITELISTED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \
|
||||
ALLOW_PROPERTY=${ALLOW_PROPERTY:-"docs.allowed.branches"}
|
||||
ALLOWED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \
|
||||
-Dexec.executable="echo" \
|
||||
-Dexec.args="\${${WHITELIST_PROPERTY}}" \
|
||||
-Dexec.args="\${${ALLOW_PROPERTY}}" \
|
||||
org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
|
||||
-P docs \
|
||||
-pl docs)
|
||||
echo "Extracted '${WHITELIST_PROPERTY}' from Maven build [${WHITELISTED_BRANCHES_VALUE}]"
|
||||
echo "Extracted '${ALLOW_PROPERTY}' from Maven build [${ALLOWED_BRANCHES_VALUE}]"
|
||||
}
|
||||
|
||||
# Stash any outstanding changes
|
||||
@@ -134,8 +134,8 @@ function add_docs_from_target() {
|
||||
|
||||
# Copies the docs by using the retrieved properties from Maven build
|
||||
function copy_docs_for_current_version() {
|
||||
if [[ "${CURRENT_BRANCH}" == "master" ]] ; then
|
||||
echo -e "Current branch is master - will copy the current docs only to the root folder"
|
||||
if [[ "${CURRENT_BRANCH}" == "main" ]] ; then
|
||||
echo -e "Current branch is main - will copy the current docs only to the root folder"
|
||||
for f in docs/target/generated-docs/*; do
|
||||
file=${f#docs/target/generated-docs/*}
|
||||
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then
|
||||
@@ -148,9 +148,9 @@ function copy_docs_for_current_version() {
|
||||
else
|
||||
echo -e "Current branch is [${CURRENT_BRANCH}]"
|
||||
# https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin
|
||||
if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then
|
||||
if [[ ",${ALLOWED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then
|
||||
mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH}
|
||||
echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder"
|
||||
echo -e "Branch [${CURRENT_BRANCH}] is allowed! Will copy the current docs to the [${CURRENT_BRANCH}] folder"
|
||||
for f in docs/target/generated-docs/*; do
|
||||
file=${f#docs/target/generated-docs/*}
|
||||
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then
|
||||
@@ -169,7 +169,7 @@ function copy_docs_for_current_version() {
|
||||
done
|
||||
COMMIT_CHANGES="yes"
|
||||
else
|
||||
echo -e "Branch [${CURRENT_BRANCH}] is not on the white list! Check out the Maven [${WHITELIST_PROPERTY}] property in
|
||||
echo -e "Branch [${CURRENT_BRANCH}] is not on the allow list! Check out the Maven [${ALLOW_PROPERTY}] property in
|
||||
[docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch."
|
||||
fi
|
||||
fi
|
||||
@@ -216,7 +216,7 @@ function commit_changes_if_applicable() {
|
||||
git commit -a -m "Sync docs from ${CURRENT_BRANCH} to gh-pages" && COMMIT_SUCCESSFUL="yes" || echo "Failed to commit changes"
|
||||
|
||||
# Uncomment the following push if you want to auto push to
|
||||
# the gh-pages branch whenever you commit to master locally.
|
||||
# the gh-pages branch whenever you commit to main locally.
|
||||
# This is a little extreme. Use with care!
|
||||
###################################################################
|
||||
if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then
|
||||
@@ -249,11 +249,11 @@ The idea of this script is to update gh-pages branch with the generated docs. Wi
|
||||
the script will work in the following manner:
|
||||
|
||||
- if there's no gh-pages / target for docs module then the script ends
|
||||
- for master branch the generated docs are copied to the root of gh-pages branch
|
||||
- for any other branch (if that branch is whitelisted) a subfolder with branch name is created
|
||||
- for main branch the generated docs are copied to the root of gh-pages branch
|
||||
- for any other branch (if that branch is allowed) a subfolder with branch name is created
|
||||
and docs are copied there
|
||||
- if the version switch is passed (-v) then a tag with (v) prefix will be retrieved and a folder
|
||||
with that version number will be created in the gh-pages branch. WARNING! No whitelist verification will take place
|
||||
with that version number will be created in the gh-pages branch. WARNING! No allow verification will take place
|
||||
- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will
|
||||
switch to gh-pages of that repo and copy the generated docs to `docs/<project-name>/<version>`
|
||||
- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will
|
||||
@@ -327,4 +327,4 @@ build_docs_if_applicable
|
||||
retrieve_doc_properties
|
||||
stash_changes
|
||||
add_docs_from_target
|
||||
checkout_previous_branch
|
||||
checkout_previous_branch
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
spring-cloud-netflix.adoc
|
||||
@@ -1,7 +1,8 @@
|
||||
include::_attributes.adoc[]
|
||||
|
||||
This project provides Netflix OSS integrations for Spring Boot apps through autoconfiguration
|
||||
and binding to the Spring Environment and other Spring programming model idioms. With a few
|
||||
simple annotations you can quickly enable and configure the common patterns inside your
|
||||
application and build large distributed systems with battle-tested Netflix components. The
|
||||
patterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix),
|
||||
Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).
|
||||
patterns provided include Service Discovery (Eureka).
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
Spring Cloud Netflix provides Netflix OSS integrations for Spring Boot apps through autoconfiguration and binding to the Spring Environment and other Spring programming model idioms. With a few simple annotations you can quickly enable and configure the common patterns inside your application and build large distributed systems with battle-tested Netflix components. The patterns provided include Service Discovery (Eureka).
|
||||
|
||||
## Features
|
||||
|
||||
Spring Cloud Netflix features:
|
||||
|
||||
* Service Discovery: Eureka instances can be registered and clients can discover the instances using Spring-managed beans
|
||||
* Service Discovery: an embedded Eureka server can be created with declarative Java configuration
|
||||
|
||||
## Getting Started
|
||||
|
||||
As long as Spring Cloud Netflix and Eureka Core are on the
|
||||
classpath any Spring Boot application with `spring-cloud-starter-netflix-eureka-client` in dependencies will try to contact a Eureka
|
||||
server on `http://localhost:8761` (the default value of
|
||||
`eureka.client.serviceUrl.defaultZone`):
|
||||
|
||||
```java
|
||||
@SpringBootApplication
|
||||
@RestController
|
||||
public class Application {
|
||||
|
||||
@RequestMapping("/")
|
||||
public String home() {
|
||||
return "Hello World";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
To run your own server use the `spring-cloud-starter-netflix-eureka-server` dependency and `@EnableEurekaServer`.
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions. You can read more on how to contribute to the project https://github.com/spring-cloud/spring-cloud-netflix#contributing[here].
|
||||
|
||||
## Community Support
|
||||
|
||||
* You can report issues through https://github.com/spring-cloud/spring-cloud-netflix/issues[Github].
|
||||
* We monitor https://stackoverflow.com/[StackOverflow] for questions with the `spring-cloud-netflix` tag.
|
||||
* You can contact our team at https://gitter.im/spring-cloud/spring-cloud[Gitter].
|
||||
|
||||
## Commercial Support
|
||||
|
||||
Commercial Support is provided as part of the https://spring.io/support[VMware Spring Runtime] offering.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -54,38 +54,16 @@ case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
#
|
||||
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
|
||||
# for the new JDKs provided by Oracle.
|
||||
#
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
|
||||
#
|
||||
# Oracle JDKs
|
||||
#
|
||||
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=`/usr/libexec/java_home`
|
||||
fi
|
||||
;;
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
@@ -130,7 +108,7 @@ if $cygwin ; then
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Migwn, ensure paths are in UNIX format before anything is touched
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
@@ -184,27 +162,28 @@ fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
local basedir=$(pwd)
|
||||
local wdir=$(pwd)
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
wdir=$(cd "$wdir/.."; pwd)
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
@@ -216,13 +195,87 @@ concat_lines() {
|
||||
fi
|
||||
}
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar"
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
curl -o "$wrapperJarPath" "$jarUrl"
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
@@ -232,22 +285,22 @@ echo "The found version is [${VERSION}]"
|
||||
|
||||
if echo $VERSION | egrep -q 'M|RC'; then
|
||||
echo Activating \"milestone\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
|
||||
echo $MAVEN_CONFIG | grep -q milestone || MAVEN_CONFIG="$MAVEN_CONFIG -Pmilestone"
|
||||
else
|
||||
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
|
||||
echo $MAVEN_CONFIG | grep -q milestone && MAVEN_CONFIG=$(echo $MAVEN_CONFIG | sed -e 's/-Pmilestone//')
|
||||
fi
|
||||
|
||||
if echo $VERSION | egrep -q 'RELEASE'; then
|
||||
echo Activating \"central\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
|
||||
echo $MAVEN_CONFIG | grep -q milestone || MAVEN_CONFIG="$MAVEN_CONFIG -Pcentral"
|
||||
else
|
||||
echo Deactivating \"central\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
|
||||
echo $MAVEN_CONFIG | grep -q central && MAVEN_CONFIG=$(echo $MAVEN_CONFIG | sed -e 's/-Pcentral//')
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||
|
||||
@@ -1,145 +1,161 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
|
||||
set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar"
|
||||
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
echo Found %WRAPPER_JAR%
|
||||
) else (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>2.0.4.BUILD-SNAPSHOT</version>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Netflix</name>
|
||||
<description>Spring Cloud Netflix</description>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>2.0.5.BUILD-SNAPSHOT</version>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<scm>
|
||||
@@ -21,25 +21,24 @@
|
||||
</scm>
|
||||
<properties>
|
||||
<bintray.package>netflix</bintray.package>
|
||||
<jackson.version>2.7.3</jackson.version>
|
||||
<spring-cloud-commons.version>2.0.3.BUILD-SNAPSHOT</spring-cloud-commons.version>
|
||||
<spring-cloud-config.version>2.0.3.BUILD-SNAPSHOT</spring-cloud-config.version>
|
||||
<spring-cloud-stream.version>Elmhurst.BUILD-SNAPSHOT</spring-cloud-stream.version>
|
||||
<!-- Has to be a stable version (not one that depends on this version of netflix): -->
|
||||
<donotreplacespring-cloud-contract.version>2.0.2.RELEASE</donotreplacespring-cloud-contract.version>
|
||||
<spring-cloud-commons.version>4.0.0-SNAPSHOT</spring-cloud-commons.version>
|
||||
<spring-cloud-config.version>4.0.0-SNAPSHOT</spring-cloud-config.version>
|
||||
|
||||
<!-- Plugin versions -->
|
||||
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
|
||||
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
|
||||
<!-- Sonar -->
|
||||
<surefire.plugin.version>2.19.1</surefire.plugin.version>
|
||||
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
|
||||
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
|
||||
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
|
||||
<sonar.language>java</sonar.language>
|
||||
<maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
|
||||
<!-- FIXME: 4.0.0 -->
|
||||
<duplicate-finder-maven-plugin.skip>true</duplicate-finder-maven-plugin.skip>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>flatten-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
@@ -59,23 +58,29 @@
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.basepom.maven</groupId>
|
||||
<artifactId>duplicate-finder-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<ignoredResourcePatterns>
|
||||
<ignoredResourcePattern>about.html</ignoredResourcePattern>
|
||||
<ignoredResourcePattern>plugin.properties</ignoredResourcePattern>
|
||||
<ignoredResourcePattern>mozilla/public-suffix-list.txt</ignoredResourcePattern>
|
||||
</ignoredResourcePatterns>
|
||||
<checkTestClasspath>false</checkTestClasspath>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-contract</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-dependencies</artifactId>
|
||||
@@ -103,61 +108,30 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-dependencies</artifactId>
|
||||
<version>${spring-cloud-stream.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-dependencies</artifactId>
|
||||
<version>${donotreplacespring-cloud-contract.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-smile</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
</dependency>
|
||||
<!-- archaius dependencies that are now runtime -->
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<version>1.8</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- end archaius deps -->
|
||||
<!-- Eureka core dep that is now optional -->
|
||||
<!-- end eureka deps -->
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
<modules>
|
||||
<module>spring-cloud-netflix-dependencies</module>
|
||||
<module>spring-cloud-netflix-archaius</module>
|
||||
<!-- Not part of the reactor build: build and deploy separately -->
|
||||
<!--module>spring-cloud-netflix-hystrix-contract</module-->
|
||||
<module>spring-cloud-netflix-core</module>
|
||||
<module>spring-cloud-netflix-hystrix-dashboard</module>
|
||||
<module>spring-cloud-netflix-hystrix-stream</module>
|
||||
<module>spring-cloud-netflix-eureka-client</module>
|
||||
<module>spring-cloud-netflix-eureka-server</module>
|
||||
<module>spring-cloud-netflix-turbine</module>
|
||||
<module>spring-cloud-netflix-turbine-stream</module>
|
||||
<module>spring-cloud-netflix-sidecar</module>
|
||||
<module>spring-cloud-netflix-zuul</module>
|
||||
<module>spring-cloud-netflix-ribbon</module>
|
||||
<module>spring-cloud-starter-netflix</module>
|
||||
<module>spring-cloud-starter-netflix-eureka-client</module>
|
||||
<module>spring-cloud-starter-netflix-eureka-server</module>
|
||||
<module>spring-cloud-netflix-eureka-client-tls-tests</module>
|
||||
<module>docs</module>
|
||||
</modules>
|
||||
<profiles>
|
||||
@@ -191,6 +165,23 @@
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<!-- FIXME: 4.0 -->
|
||||
<repository>
|
||||
<id>netflix-snapshots</id>
|
||||
<name>Netflix Snapshots</name>
|
||||
<url>https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-snapshots</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>netflix-candidates</id>
|
||||
<name>Netflix Candidates</name>
|
||||
<url>https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-candidates</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
(cd spring-cloud-netflix-hystrix-contract && ../mvnw clean install -B -Pdocs ${@})
|
||||
./mvnw clean install -B -Pdocs ${@}
|
||||
@@ -1,4 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
|
||||
(cd spring-cloud-netflix-hystrix-contract && ../mvnw clean install -B -Pdocs -DskipTests)
|
||||
./mvnw clean install -B -Pdocs -DskipTests -fae
|
||||
|
||||
@@ -4,7 +4,7 @@ set -o errexit
|
||||
|
||||
mkdir -p target
|
||||
|
||||
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/brewery/master/runAcceptanceTests.sh"
|
||||
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/brewery/3.1.x/runAcceptanceTests.sh"
|
||||
AT_WHAT_TO_TEST="EUREKA"
|
||||
|
||||
cd target
|
||||
@@ -18,7 +18,7 @@ echo "Killing all running apps"
|
||||
|
||||
./runAcceptanceTests.sh -t "${AT_WHAT_TO_TEST}" --killattheend
|
||||
|
||||
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/tests/master/scripts/runTests.sh"
|
||||
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/tests/main/scripts/runTests.sh"
|
||||
|
||||
curl "${SCRIPT_URL}" --output runIntegrationTests.sh
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<version>2.0.4.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
||||
<artifactId>spring-cloud-netflix-archaius</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Netflix Archaius</name>
|
||||
<description>Spring Cloud Netflix Archaius</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-context</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
-227
@@ -1,227 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.apache.commons.configuration.ConfigurationBuilder;
|
||||
import org.apache.commons.configuration.EnvironmentConfiguration;
|
||||
import org.apache.commons.configuration.SystemConfiguration;
|
||||
import org.apache.commons.configuration.event.ConfigurationEvent;
|
||||
import org.apache.commons.configuration.event.ConfigurationListener;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.netflix.config.AggregatedConfiguration;
|
||||
import com.netflix.config.ConcurrentCompositeConfiguration;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DeploymentContext;
|
||||
import com.netflix.config.DynamicProperty;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.config.DynamicURLConfiguration;
|
||||
|
||||
import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ ConcurrentCompositeConfiguration.class,
|
||||
ConfigurationBuilder.class })
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class ArchaiusAutoConfiguration {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ArchaiusAutoConfiguration.class);
|
||||
|
||||
private static final AtomicBoolean initialized = new AtomicBoolean(false);
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment env;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AbstractConfiguration> externalConfigurations = new ArrayList<>();
|
||||
|
||||
private static DynamicURLConfiguration defaultURLConfig;
|
||||
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
if (defaultURLConfig != null) {
|
||||
defaultURLConfig.stopLoading();
|
||||
}
|
||||
setStatic(ConfigurationManager.class, "instance", null);
|
||||
setStatic(ConfigurationManager.class, "customConfigurationInstalled", false);
|
||||
setStatic(DynamicPropertyFactory.class, "config", null);
|
||||
setStatic(DynamicPropertyFactory.class, "initializedWithDefaultConfig", false);
|
||||
setStatic(DynamicProperty.class, "dynamicPropertySupportImpl", null);
|
||||
initialized.compareAndSet(true, false);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public static ConfigurableEnvironmentConfiguration configurableEnvironmentConfiguration(ConfigurableEnvironment env,
|
||||
ApplicationContext context) {
|
||||
Map<String, AbstractConfiguration> abstractConfigurationMap = context.getBeansOfType(AbstractConfiguration.class);
|
||||
List<AbstractConfiguration> externalConfigurations = new ArrayList<>(abstractConfigurationMap.values());
|
||||
ConfigurableEnvironmentConfiguration envConfig = new ConfigurableEnvironmentConfiguration(env);
|
||||
configureArchaius(envConfig, env, externalConfigurations);
|
||||
return envConfig;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Health.class)
|
||||
protected static class ArchaiusEndpointConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnEnabledEndpoint
|
||||
protected ArchaiusEndpoint archaiusEndpoint() {
|
||||
return new ArchaiusEndpoint();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", matchIfMissing = true)
|
||||
@ConditionalOnClass(EnvironmentChangeEvent.class)
|
||||
protected static class PropagateEventsConfiguration
|
||||
implements ApplicationListener<EnvironmentChangeEvent> {
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(EnvironmentChangeEvent event) {
|
||||
AbstractConfiguration manager = ConfigurationManager.getConfigInstance();
|
||||
for (String key : event.getKeys()) {
|
||||
for (ConfigurationListener listener : manager
|
||||
.getConfigurationListeners()) {
|
||||
Object source = event.getSource();
|
||||
// TODO: Handle add vs set vs delete?
|
||||
int type = AbstractConfiguration.EVENT_SET_PROPERTY;
|
||||
String value = this.env.getProperty(key);
|
||||
boolean beforeUpdate = false;
|
||||
listener.configurationChanged(new ConfigurationEvent(source, type,
|
||||
key, value, beforeUpdate));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void configureArchaius(ConfigurableEnvironmentConfiguration envConfig, ConfigurableEnvironment env, List<AbstractConfiguration> externalConfigurations) {
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
String appName = env.getProperty("spring.application.name");
|
||||
if (appName == null) {
|
||||
appName = "application";
|
||||
log.warn("No spring.application.name found, defaulting to 'application'");
|
||||
}
|
||||
System.setProperty(DeploymentContext.ContextKey.appId.getKey(), appName);
|
||||
|
||||
ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
|
||||
|
||||
// support to add other Configurations (Jdbc, DynamoDb, Zookeeper, jclouds,
|
||||
// etc...)
|
||||
if (externalConfigurations != null) {
|
||||
for (AbstractConfiguration externalConfig : externalConfigurations) {
|
||||
config.addConfiguration(externalConfig);
|
||||
}
|
||||
}
|
||||
config.addConfiguration(envConfig,
|
||||
ConfigurableEnvironmentConfiguration.class.getSimpleName());
|
||||
|
||||
defaultURLConfig = new DynamicURLConfiguration();
|
||||
try {
|
||||
config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
log.error("Cannot create config from " + defaultURLConfig, ex);
|
||||
}
|
||||
|
||||
// TODO: sys/env above urls?
|
||||
if (!Boolean.getBoolean(DISABLE_DEFAULT_SYS_CONFIG)) {
|
||||
SystemConfiguration sysConfig = new SystemConfiguration();
|
||||
config.addConfiguration(sysConfig, SYS_CONFIG_NAME);
|
||||
}
|
||||
if (!Boolean.getBoolean(DISABLE_DEFAULT_ENV_CONFIG)) {
|
||||
EnvironmentConfiguration environmentConfiguration = new EnvironmentConfiguration();
|
||||
config.addConfiguration(environmentConfiguration, ENV_CONFIG_NAME);
|
||||
}
|
||||
|
||||
ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
|
||||
config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES);
|
||||
config.setContainerConfigurationIndex(
|
||||
config.getIndexOfConfiguration(appOverrideConfig));
|
||||
|
||||
addArchaiusConfiguration(config);
|
||||
}
|
||||
else {
|
||||
// TODO: reinstall ConfigurationManager
|
||||
log.warn(
|
||||
"Netflix ConfigurationManager has already been installed, unable to re-install");
|
||||
}
|
||||
}
|
||||
|
||||
private static void addArchaiusConfiguration(ConcurrentCompositeConfiguration config) {
|
||||
if (ConfigurationManager.isConfigurationInstalled()) {
|
||||
AbstractConfiguration installedConfiguration = ConfigurationManager
|
||||
.getConfigInstance();
|
||||
if (installedConfiguration instanceof ConcurrentCompositeConfiguration) {
|
||||
ConcurrentCompositeConfiguration configInstance = (ConcurrentCompositeConfiguration) installedConfiguration;
|
||||
configInstance.addConfiguration(config);
|
||||
}
|
||||
else {
|
||||
installedConfiguration.append(config);
|
||||
if (!(installedConfiguration instanceof AggregatedConfiguration)) {
|
||||
log.warn(
|
||||
"Appending a configuration to an existing non-aggregated installed configuration will have no effect");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ConfigurationManager.install(config);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setStatic(Class<?> type, String name, Object value) {
|
||||
// Hack a private static field
|
||||
Field field = ReflectionUtils.findField(type, name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
ReflectionUtils.setField(field, null, value);
|
||||
}
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ArchaiusDelegatingProxyUtils {
|
||||
|
||||
public static String APPLICATION_CONTEXT = ApplicationContext.class.getName();
|
||||
|
||||
public static <T> T getNamedInstance(Class<T> type, String name) {
|
||||
ApplicationContext context = (ApplicationContext) ConfigurationManager
|
||||
.getConfigInstance().getProperty(APPLICATION_CONTEXT);
|
||||
return context != null && context.containsBean(name) ? context
|
||||
.getBean(name, type) : null;
|
||||
}
|
||||
|
||||
public static <T> T getInstanceWithPrefix(Class<T> type, String prefix) {
|
||||
String name = prefix + type.getSimpleName();
|
||||
return getNamedInstance(type, name);
|
||||
}
|
||||
|
||||
public static void addApplicationContext(ConfigurableApplicationContext context) {
|
||||
AbstractConfiguration config = ConfigurationManager.getConfigInstance();
|
||||
config.clearProperty(APPLICATION_CONTEXT);
|
||||
config.setProperty(APPLICATION_CONTEXT, context);
|
||||
}
|
||||
|
||||
}
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.apache.commons.configuration.EnvironmentConfiguration;
|
||||
import org.apache.commons.configuration.SystemConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
|
||||
import com.netflix.config.ConcurrentCompositeConfiguration;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Endpoint(id = "archaius")
|
||||
public class ArchaiusEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
AbstractConfiguration config = ConfigurationManager.getConfigInstance();
|
||||
if (config instanceof ConcurrentCompositeConfiguration) {
|
||||
ConcurrentCompositeConfiguration composite = (ConcurrentCompositeConfiguration) config;
|
||||
for (Configuration item : composite.getConfigurations()) {
|
||||
append(map, item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
append(map, config);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void append(Map<String, Object> map, Configuration config) {
|
||||
if (config instanceof ConfigurableEnvironmentConfiguration) {
|
||||
return;
|
||||
}
|
||||
if (config instanceof SystemConfiguration) {
|
||||
return;
|
||||
}
|
||||
if (config instanceof EnvironmentConfiguration) {
|
||||
return;
|
||||
}
|
||||
for (Iterator<String> iter = config.getKeys(); iter.hasNext();) {
|
||||
String key = iter.next();
|
||||
map.put(key, config.getProperty(key));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.EnumerablePropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class ConfigurableEnvironmentConfiguration extends AbstractConfiguration {
|
||||
|
||||
private final ConfigurableEnvironment environment;
|
||||
|
||||
public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addPropertyDirect(String key, Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return !getKeys().hasNext(); // TODO: find a better way to do this
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return this.environment.containsProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String key) {
|
||||
return this.environment.getProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getKeys() {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Map.Entry<String, PropertySource<?>> entry : getPropertySources().entrySet()) {
|
||||
PropertySource<?> source = entry.getValue();
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source;
|
||||
for (String name : enumerable.getPropertyNames()) {
|
||||
result.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
}
|
||||
|
||||
private Map<String, PropertySource<?>> getPropertySources() {
|
||||
Map<String, PropertySource<?>> map = new LinkedHashMap<>();
|
||||
MutablePropertySources sources = (this.environment != null ? this.environment
|
||||
.getPropertySources() : new StandardEnvironment().getPropertySources());
|
||||
for (PropertySource<?> source : sources) {
|
||||
extract("", map, source);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void extract(String root, Map<String, PropertySource<?>> map,
|
||||
PropertySource<?> source) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
for (PropertySource<?> nest : ((CompositePropertySource) source)
|
||||
.getPropertySources()) {
|
||||
extract(source.getName() + ":", map, nest);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map.put(root + source.getName(), source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"properties": [
|
||||
{
|
||||
"defaultValue": "true",
|
||||
"name": "archaius.propagate.environmentChangedEvent",
|
||||
"description": "Propagates EnvironmentChanged events to Archaius ConfigurationManager.",
|
||||
"type": "java.lang.Boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.apache.commons.configuration.event.ConfigurationEvent;
|
||||
import org.apache.commons.configuration.event.ConfigurationListener;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.config.DynamicStringProperty;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ArchaiusAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
private Object propertyValue;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationCreated() {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class);
|
||||
AbstractConfiguration config = this.context
|
||||
.getBean(ConfigurableEnvironmentConfiguration.class);
|
||||
assertNotNull(config.getString("java.io.tmpdir"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void environmentChangeEventPropagated() {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class);
|
||||
ConfigurationManager.getConfigInstance().addConfigurationListener(
|
||||
new ConfigurationListener() {
|
||||
@Override
|
||||
public void configurationChanged(ConfigurationEvent event) {
|
||||
if (event.getPropertyName().equals("my.prop")) {
|
||||
ArchaiusAutoConfigurationTests.this.propertyValue = event
|
||||
.getPropertyValue();
|
||||
}
|
||||
}
|
||||
});
|
||||
EnvironmentTestUtils.addEnvironment(this.context, "my.prop=my.newval");
|
||||
this.context.publishEvent(new EnvironmentChangeEvent(Collections
|
||||
.singleton("my.prop")));
|
||||
assertEquals("my.newval", this.propertyValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationWithoutExternalConfigurations() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class);
|
||||
DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance()
|
||||
.getStringProperty("db.property", null);
|
||||
DynamicStringProperty staticProperty = DynamicPropertyFactory.getInstance()
|
||||
.getStringProperty("archaius.file.property", null);
|
||||
|
||||
assertNull(dbProperty.getValue());
|
||||
assertNotNull(staticProperty.getValue());
|
||||
assertEquals("Static config file property", staticProperty.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationWithInjectedConfiguration() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class, TestArchaiusExternalConfiguration.class);
|
||||
DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance()
|
||||
.getStringProperty("db.property", null);
|
||||
DynamicStringProperty secondDbProperty = DynamicPropertyFactory.getInstance()
|
||||
.getStringProperty("db.second.property", null);
|
||||
DynamicStringProperty staticProperty = DynamicPropertyFactory.getInstance()
|
||||
.getStringProperty("archaius.file.property", null);
|
||||
|
||||
assertNotNull(dbProperty.getValue());
|
||||
assertNotNull(secondDbProperty.getValue());
|
||||
assertNotNull(staticProperty.getValue());
|
||||
assertEquals("this is a db property", dbProperty.getValue());
|
||||
assertEquals("this is another db property", secondDbProperty.getValue());
|
||||
assertEquals("Static config file property", staticProperty.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
|
||||
import com.netflix.config.ConcurrentCompositeConfiguration;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ArchaiusEndpointTests {
|
||||
|
||||
private ArchaiusEndpoint endpoint = new ArchaiusEndpoint();
|
||||
|
||||
@Test
|
||||
public void detectsPropertiesWhenSet() {
|
||||
ConfigurationManager.getConfigInstance().setProperty("foo", "bar");
|
||||
assertTrue(this.endpoint.invoke().containsKey("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotIncludeSpringEnvironment() {
|
||||
ConcurrentCompositeConfiguration composite = new ConcurrentCompositeConfiguration(
|
||||
ConfigurationManager.getConfigInstance());
|
||||
ConfigurableEnvironmentConfiguration config = new ConfigurableEnvironmentConfiguration(
|
||||
new StandardEnvironment());
|
||||
assertTrue(config.containsKey("user.dir"));
|
||||
composite.addConfiguration(config);
|
||||
ConfigurationManager.getConfigInstance().setProperty("foo", "bar");
|
||||
Map<String, Object> map = this.endpoint.invoke();
|
||||
assertTrue(map.containsKey("foo"));
|
||||
assertFalse(map.containsKey("user.dir"));
|
||||
}
|
||||
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.config.ConcurrentMapConfiguration;
|
||||
|
||||
/**
|
||||
* @author Alexandru-George Burghelea
|
||||
*/
|
||||
@Configuration
|
||||
public class TestArchaiusExternalConfiguration {
|
||||
|
||||
@Bean
|
||||
@Qualifier("dynamicConfiguration")
|
||||
public AbstractConfiguration createDynamicConfiguration() {
|
||||
ConcurrentMapConfiguration config = new ConcurrentMapConfiguration();
|
||||
config.addProperty("db.property","this is a db property");
|
||||
config.addProperty("db.second.property","this is another db property");
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
archaius.file.property=Static config file property
|
||||
db.second.property=It should be overridden
|
||||
@@ -1,186 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>2.0.4.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Netflix Core</name>
|
||||
<description>Spring Cloud Netflix Core</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-reactor-netty</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec-http</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex</groupId>
|
||||
<artifactId>rxjava-reactive-streams</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.retry</groupId>
|
||||
<artifactId>spring-retry</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-context</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-serialization</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-metrics-event-stream</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-javanica</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-apache-client4</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-ribbon</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-test-support</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>java8plus</id>
|
||||
<activation>
|
||||
<jdk>[1.8,2.0)</jdk>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
|
||||
/**
|
||||
* Convenience annotation for clients to enable Hystrix circuit breakers (specifically).
|
||||
* Use this (optionally) in case you want discovery and know for sure that it is Hystrix
|
||||
* you want. All it does is turn on circuit breakers and let the autoconfiguration find
|
||||
* the Hystrix classes if they are available (i.e. you need Hystrix on the classpath as
|
||||
* well).
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@EnableCircuitBreaker
|
||||
public @interface EnableHystrix {
|
||||
|
||||
}
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
|
||||
import com.netflix.hystrix.metric.consumer.HystrixDashboardStream;
|
||||
import com.netflix.hystrix.serial.SerialHystrixDashboardData;
|
||||
import io.micrometer.core.instrument.binder.hystrix.HystrixMetricsBinder;
|
||||
import org.reactivestreams.Publisher;
|
||||
import rx.Observable;
|
||||
import rx.RxReactiveStreams;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.actuator.HasFeatures;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.DispatcherHandler;
|
||||
|
||||
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE;
|
||||
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.SERVLET;
|
||||
|
||||
/**
|
||||
* Auto configuration for Hystrix.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Hystrix.class, HealthIndicator.class, HealthIndicatorAutoConfiguration.class })
|
||||
@AutoConfigureAfter({ HealthIndicatorAutoConfiguration.class })
|
||||
public class HystrixAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledHealthIndicator("hystrix")
|
||||
public HystrixHealthIndicator hystrixHealthIndicator() {
|
||||
return new HystrixHealthIndicator();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "management.metrics.binders.hystrix.enabled", matchIfMissing = true)
|
||||
@ConditionalOnClass({ HystrixMetricsBinder.class })
|
||||
protected static class HystrixMetricsConfiguration {
|
||||
@Bean
|
||||
public HystrixMetricsBinder hystrixMetricsBinder() {
|
||||
return new HystrixMetricsBinder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See original {@link org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaEndpointAutoConfiguration}
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication(type = SERVLET)
|
||||
@ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled
|
||||
@ConditionalOnClass({ HystrixMetricsStreamServlet.class })
|
||||
@EnableConfigurationProperties(HystrixProperties.class)
|
||||
protected static class HystrixServletAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledEndpoint
|
||||
public HystrixStreamEndpoint hystrixStreamEndpoint(HystrixProperties properties) {
|
||||
return new HystrixStreamEndpoint(properties.getConfig());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HasFeatures hystrixStreamFeature() {
|
||||
return HasFeatures.namedFeature("Hystrix Stream Servlet", HystrixMetricsStreamServlet.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication(type = REACTIVE)
|
||||
@ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled
|
||||
@ConditionalOnClass({ DispatcherHandler.class })
|
||||
@EnableConfigurationProperties(HystrixProperties.class)
|
||||
protected static class HystrixWebfluxManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledEndpoint
|
||||
public HystrixWebfluxEndpoint hystrixWebfluxController() {
|
||||
Observable<String> serializedDashboardData = HystrixDashboardStream.getInstance().observe()
|
||||
.concatMap(dashboardData -> Observable.from(SerialHystrixDashboardData.toMultipleJsonStrings(dashboardData)));
|
||||
Publisher<String> publisher = RxReactiveStreams.toPublisher(serializedDashboardData);
|
||||
return new HystrixWebfluxEndpoint(publisher);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HasFeatures hystrixStreamFeature() {
|
||||
return HasFeatures.namedFeature("Hystrix Stream Webflux", HystrixWebfluxEndpoint.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import org.apache.catalina.core.ApplicationContext;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.cloud.client.actuator.HasFeatures;
|
||||
import org.springframework.cloud.client.actuator.NamedFeature;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Christian Dupuis
|
||||
* @author Venil Noronha
|
||||
*/
|
||||
@Configuration
|
||||
public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Bean
|
||||
public HystrixCommandAspect hystrixCommandAspect() {
|
||||
return new HystrixCommandAspect();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HystrixShutdownHook hystrixShutdownHook() {
|
||||
return new HystrixShutdownHook();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HasFeatures hystrixFeature() {
|
||||
return HasFeatures.namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link DisposableBean} that makes sure that Hystrix internal state is cleared when
|
||||
* {@link ApplicationContext} shuts down.
|
||||
*/
|
||||
private class HystrixShutdownHook implements DisposableBean {
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
// Just call Hystrix to reset thread pool etc.
|
||||
Hystrix.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-197
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||
import com.netflix.hystrix.HystrixCommandKey;
|
||||
import com.netflix.hystrix.HystrixCommandProperties;
|
||||
import com.netflix.hystrix.HystrixObservableCommand;
|
||||
import com.netflix.hystrix.HystrixObservableCommand.Setter;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import rx.Observable;
|
||||
import rx.RxReactiveStreams;
|
||||
|
||||
/**
|
||||
* Utility class to wrap a {@see Publisher} in a {@see HystrixObservableCommand}. Good for
|
||||
* use in a Spring WebFlux application. Allows more flexibility than the @HystrixCommand
|
||||
* annotation.
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class HystrixCommands {
|
||||
|
||||
public static <T> PublisherBuilder<T> from(Publisher<T> publisher) {
|
||||
return new PublisherBuilder<>(publisher);
|
||||
}
|
||||
|
||||
public static class PublisherBuilder<T> {
|
||||
private final Publisher<T> publisher;
|
||||
private String commandName;
|
||||
private String groupName;
|
||||
private Function<Throwable, Publisher<T>> fallback;
|
||||
private Setter setter;
|
||||
private HystrixCommandProperties.Setter commandProperties;
|
||||
private boolean eager = false;
|
||||
private Function<HystrixObservableCommand<T>, Observable<T>> toObservable;
|
||||
|
||||
public PublisherBuilder(Publisher<T> publisher) {
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> commandName(String commandName) {
|
||||
this.commandName = commandName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> groupName(String groupName) {
|
||||
this.groupName = groupName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> fallback(Publisher<T> fallback) {
|
||||
this.fallback = throwable -> fallback;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> fallback(Function<Throwable, Publisher<T>> fallback) {
|
||||
this.fallback = fallback;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> setter(Setter setter) {
|
||||
this.setter = setter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> commandProperties(
|
||||
HystrixCommandProperties.Setter commandProperties) {
|
||||
this.commandProperties = commandProperties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> commandProperties(
|
||||
Function<HystrixCommandProperties.Setter, HystrixCommandProperties.Setter> commandProperties) {
|
||||
if (commandProperties == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"commandProperties must not both be null");
|
||||
}
|
||||
return this.commandProperties(
|
||||
commandProperties.apply(HystrixCommandProperties.Setter()));
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> eager() {
|
||||
this.eager = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublisherBuilder<T> toObservable(Function<HystrixObservableCommand<T>, Observable<T>> toObservable) {
|
||||
this.toObservable = toObservable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Publisher<T> build() {
|
||||
if (!StringUtils.hasText(commandName) && setter == null) {
|
||||
throw new IllegalStateException("commandName and setter can not both be empty");
|
||||
}
|
||||
Setter setterToUse = getSetter();
|
||||
|
||||
PublisherHystrixCommand<T> command = new PublisherHystrixCommand<>(setterToUse, this.publisher, this.fallback);
|
||||
|
||||
Observable<T> observable = getObservableFunction().apply(command);
|
||||
|
||||
return RxReactiveStreams.toPublisher(observable);
|
||||
}
|
||||
|
||||
public Function<HystrixObservableCommand<T>, Observable<T>> getObservableFunction() {
|
||||
Function<HystrixObservableCommand<T>, Observable<T>> observableFunc;
|
||||
|
||||
if (this.toObservable != null) {
|
||||
observableFunc = this.toObservable;
|
||||
} else if (this.eager) {
|
||||
observableFunc = cmd -> cmd.observe();
|
||||
} else { // apply a default onBackpressureBuffer if not eager
|
||||
observableFunc = cmd -> cmd.toObservable().onBackpressureBuffer();
|
||||
}
|
||||
return observableFunc;
|
||||
}
|
||||
|
||||
public Setter getSetter() {
|
||||
Setter setterToUse;
|
||||
if (this.setter != null) {
|
||||
setterToUse = this.setter;
|
||||
} else {
|
||||
String groupNameToUse;
|
||||
if (StringUtils.hasText(this.groupName)) {
|
||||
groupNameToUse = this.groupName;
|
||||
} else {
|
||||
groupNameToUse = commandName + "group";
|
||||
}
|
||||
|
||||
HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(groupNameToUse);
|
||||
HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(this.commandName);
|
||||
HystrixCommandProperties.Setter commandProperties = this.commandProperties != null
|
||||
? this.commandProperties
|
||||
: HystrixCommandProperties.Setter();
|
||||
setterToUse = Setter.withGroupKey(groupKey).andCommandKey(commandKey)
|
||||
.andCommandPropertiesDefaults(commandProperties);
|
||||
}
|
||||
return setterToUse;
|
||||
}
|
||||
|
||||
public Flux<T> toFlux() {
|
||||
return Flux.from(build());
|
||||
}
|
||||
|
||||
public Mono<T> toMono() {
|
||||
return Mono.from(build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PublisherHystrixCommand<T> extends HystrixObservableCommand<T> {
|
||||
|
||||
private Publisher<T> publisher;
|
||||
private Function<Throwable, Publisher<T>> fallback;
|
||||
|
||||
protected PublisherHystrixCommand(Setter setter, Publisher<T> publisher,
|
||||
Function<Throwable, Publisher<T>> fallback) {
|
||||
super(setter);
|
||||
this.publisher = publisher;
|
||||
this.fallback = fallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Observable<T> construct() {
|
||||
return RxReactiveStreams.toObservable(publisher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Observable<T> resumeWithFallback() {
|
||||
if (this.fallback != null) {
|
||||
Publisher<T> fallbackPublisher = fallback.apply(getExecutionException());
|
||||
return RxReactiveStreams.toObservable(fallbackPublisher);
|
||||
}
|
||||
return super.resumeWithFallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class HystrixConstants {
|
||||
|
||||
public static final String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream";
|
||||
|
||||
private HystrixConstants() {
|
||||
throw new AssertionError("Must not instantiate constant utility class");
|
||||
}
|
||||
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health.Builder;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
|
||||
import com.netflix.hystrix.HystrixCircuitBreaker;
|
||||
import com.netflix.hystrix.HystrixCommandMetrics;
|
||||
|
||||
/**
|
||||
* A {@link HealthIndicator} implementation for Hystrix circuit breakers.
|
||||
* <p>
|
||||
* This default implementation will not change the system state (e.g. <code>OK</code>) but
|
||||
* includes all open circuits by name.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
public class HystrixHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN");
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Builder builder) throws Exception {
|
||||
List<String> openCircuitBreakers = new ArrayList<>();
|
||||
|
||||
// Collect all open circuit breakers from Hystrix
|
||||
for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) {
|
||||
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory
|
||||
.getInstance(metrics.getCommandKey());
|
||||
if (circuitBreaker != null && circuitBreaker.isOpen()) {
|
||||
openCircuitBreakers.add(metrics.getCommandGroup().name() + "::"
|
||||
+ metrics.getCommandKey().name());
|
||||
}
|
||||
}
|
||||
|
||||
// If there is at least one open circuit report OUT_OF_SERVICE adding the command
|
||||
// group
|
||||
// and key name
|
||||
if (!openCircuitBreakers.isEmpty()) {
|
||||
builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers",
|
||||
openCircuitBreakers);
|
||||
}
|
||||
else {
|
||||
builder.up();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Venil Noronha
|
||||
* @author Gregor Zurowski
|
||||
*/
|
||||
@ConfigurationProperties("hystrix.metrics")
|
||||
public class HystrixMetricsProperties {
|
||||
|
||||
/** Enable Hystrix metrics polling. Defaults to true. */
|
||||
private boolean enabled = true;
|
||||
|
||||
/** Interval between subsequent polling of metrics. Defaults to 2000 ms. */
|
||||
private Integer pollingIntervalMs = 2000;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Integer getPollingIntervalMs() {
|
||||
return pollingIntervalMs;
|
||||
}
|
||||
|
||||
public void setPollingIntervalMs(Integer pollingIntervalMs) {
|
||||
this.pollingIntervalMs = pollingIntervalMs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
HystrixMetricsProperties that = (HystrixMetricsProperties) o;
|
||||
return enabled == that.enabled &&
|
||||
Objects.equals(pollingIntervalMs, that.pollingIntervalMs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(enabled, pollingIntervalMs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("HystrixMetricsProperties{")
|
||||
.append("enabled=").append(enabled).append(", ")
|
||||
.append("pollingIntervalMs=").append(pollingIntervalMs)
|
||||
.append("}").toString();
|
||||
}
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for Hystrix Servlet.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "management.endpoint.hystrix")
|
||||
public class HystrixProperties {
|
||||
|
||||
/**
|
||||
* Hystrix settings. These are traditionally set using servlet parameters. Refer to
|
||||
* the documentation of Hystrix for more details.
|
||||
*/
|
||||
private final Map<String, String> config = new HashMap<>();
|
||||
|
||||
public Map<String, String> getConfig() {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointServlet;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.boot.actuate.endpoint.annotation.Endpoint} to expose a Jolokia {@link HystrixMetricsStreamServlet}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@ServletEndpoint(id = "hystrix.stream")
|
||||
public class HystrixStreamEndpoint implements Supplier<EndpointServlet> {
|
||||
|
||||
private final Map<String, String> initParameters;
|
||||
|
||||
public HystrixStreamEndpoint(Map<String, String> initParameters) {
|
||||
this.initParameters = initParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EndpointServlet get() {
|
||||
return new EndpointServlet(HystrixMetricsStreamServlet.class)
|
||||
.withInitParameters(this.initParameters);
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@RestControllerEndpoint(id = "hystrix.stream")
|
||||
public class HystrixWebfluxEndpoint {
|
||||
|
||||
private final Flux<String> stream;
|
||||
|
||||
public HystrixWebfluxEndpoint(Publisher<String> dashboardData) {
|
||||
stream = Flux.interval(Duration.ofMillis(500)).map(aLong -> "{\"type\":\"ping\"}")
|
||||
.mergeWith(dashboardData).share();
|
||||
}
|
||||
|
||||
// path needs to be empty, so it registers correct as /actuator/hystrix.stream
|
||||
@GetMapping(path = "", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public Flux<String> hystrixStream() {
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix.security;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration.HystrixSecurityCondition;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
import com.netflix.hystrix.strategy.HystrixPlugins;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
|
||||
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
|
||||
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
|
||||
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
*/
|
||||
@Configuration
|
||||
@Conditional(HystrixSecurityCondition.class)
|
||||
@ConditionalOnClass({ Hystrix.class, SecurityContext.class })
|
||||
public class HystrixSecurityAutoConfiguration {
|
||||
private static final Log LOGGER = LogFactory.getLog(HystrixSecurityAutoConfiguration.class);
|
||||
@Autowired(required = false)
|
||||
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
// Keeps references of existing Hystrix plugins.
|
||||
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
|
||||
.getEventNotifier();
|
||||
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
|
||||
.getMetricsPublisher();
|
||||
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
|
||||
.getPropertiesStrategy();
|
||||
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance()
|
||||
.getCommandExecutionHook();
|
||||
HystrixConcurrencyStrategy concurrencyStrategy = detectRegisteredConcurrencyStrategy();
|
||||
|
||||
HystrixPlugins.reset();
|
||||
|
||||
// Registers existing plugins excepts the Concurrent Strategy plugin.
|
||||
HystrixPlugins.getInstance().registerConcurrencyStrategy(
|
||||
new SecurityContextConcurrencyStrategy(concurrencyStrategy));
|
||||
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
|
||||
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
|
||||
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
|
||||
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
|
||||
}
|
||||
|
||||
private HystrixConcurrencyStrategy detectRegisteredConcurrencyStrategy() {
|
||||
HystrixConcurrencyStrategy registeredStrategy = HystrixPlugins.getInstance()
|
||||
.getConcurrencyStrategy();
|
||||
if (existingConcurrencyStrategy == null) {
|
||||
return registeredStrategy;
|
||||
}
|
||||
//Hystrix registered a default Strategy.
|
||||
if (registeredStrategy instanceof HystrixConcurrencyStrategyDefault){
|
||||
return existingConcurrencyStrategy;
|
||||
}
|
||||
//If registeredStrategy not the default and not some use bean of existingConcurrencyStrategy.
|
||||
if (!existingConcurrencyStrategy.equals(registeredStrategy)){
|
||||
LOGGER.warn("Multiple HystrixConcurrencyStrategy detected. Bean of HystrixConcurrencyStrategy was used.");
|
||||
}
|
||||
return existingConcurrencyStrategy;
|
||||
}
|
||||
|
||||
static class HystrixSecurityCondition extends AllNestedConditions {
|
||||
|
||||
public HystrixSecurityCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(name = "hystrix.shareSecurityContext")
|
||||
static class ShareSecurityContext {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix.security;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.netflix.hystrix.HystrixThreadPoolProperties;
|
||||
import org.springframework.security.concurrent.DelegatingSecurityContextCallable;
|
||||
|
||||
import com.netflix.hystrix.HystrixThreadPoolKey;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
|
||||
import com.netflix.hystrix.strategy.properties.HystrixProperty;
|
||||
|
||||
/**
|
||||
* @author daniellavoie
|
||||
*/
|
||||
public class SecurityContextConcurrencyStrategy extends HystrixConcurrencyStrategy {
|
||||
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
|
||||
|
||||
public SecurityContextConcurrencyStrategy(
|
||||
HystrixConcurrencyStrategy existingConcurrencyStrategy) {
|
||||
this.existingConcurrencyStrategy = existingConcurrencyStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
|
||||
return existingConcurrencyStrategy != null
|
||||
? existingConcurrencyStrategy.getBlockingQueue(maxQueueSize)
|
||||
: super.getBlockingQueue(maxQueueSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> HystrixRequestVariable<T> getRequestVariable(
|
||||
HystrixRequestVariableLifecycle<T> rv) {
|
||||
return existingConcurrencyStrategy != null
|
||||
? existingConcurrencyStrategy.getRequestVariable(rv)
|
||||
: super.getRequestVariable(rv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
|
||||
HystrixProperty<Integer> corePoolSize,
|
||||
HystrixProperty<Integer> maximumPoolSize,
|
||||
HystrixProperty<Integer> keepAliveTime, TimeUnit unit,
|
||||
BlockingQueue<Runnable> workQueue) {
|
||||
return existingConcurrencyStrategy != null
|
||||
? existingConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize,
|
||||
maximumPoolSize, keepAliveTime, unit, workQueue)
|
||||
: super.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize,
|
||||
keepAliveTime, unit, workQueue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
|
||||
return existingConcurrencyStrategy != null
|
||||
? existingConcurrencyStrategy.getThreadPool(threadPoolKey, threadPoolProperties)
|
||||
: super.getThreadPool(threadPoolKey, threadPoolProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Callable<T> wrapCallable(Callable<T> callable) {
|
||||
return existingConcurrencyStrategy != null
|
||||
? existingConcurrencyStrategy
|
||||
.wrapCallable(new DelegatingSecurityContextCallable<T>(callable))
|
||||
: super.wrapCallable(new DelegatingSecurityContextCallable<T>(callable));
|
||||
}
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"properties": [
|
||||
{
|
||||
"defaultValue": "true",
|
||||
"name": "management.metrics.binders.hystrix.enabled",
|
||||
"description": "Enables creation of OK Http Client factory beans.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": false,
|
||||
"name": "hystrix.shareSecurityContext",
|
||||
"description": "Enables auto-configuration of the Hystrix concurrency strategy plugin hook who will transfer the `SecurityContext` from your main thread to the one used by the Hystrix command.",
|
||||
"type": "java.lang.Boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\
|
||||
org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration
|
||||
|
||||
org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\
|
||||
org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
/**
|
||||
* A test suite for probing weird ordering problems in the tests.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({
|
||||
// org.springframework.cloud.netflix.test.OkHttpClientConfigurationTests.class,
|
||||
// org.springframework.cloud.netflix.test.ApacheHttpClientConfigurationTests.class,
|
||||
// org.springframework.cloud.netflix.hystrix.HystrixCommandsTests.class,
|
||||
// org.springframework.cloud.netflix.hystrix.HystrixOnlyTests.class,
|
||||
// org.springframework.cloud.netflix.hystrix.security.HystrixSecurityTests.class,
|
||||
// org.springframework.cloud.netflix.hystrix.security.HystrixSecurityNoFeignTests.class,
|
||||
// org.springframework.cloud.netflix.hystrix.HystrixStreamEndpointTests.class,
|
||||
// org.springframework.cloud.netflix.hystrix.HystrixConfigurationTests.class,
|
||||
// org.springframework.cloud.netflix.resttemplate.RestTemplateRetryTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorOverridesRetryTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonUtilsTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.test.RibbonClientDefaultConfigurationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientConfigurationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactoryTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.SpringRetryEnabledTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.PlainRibbonClientPreprocessorIntegrationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClientTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpRequestTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponseTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorIntegrationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientsPreprocessorIntegrationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientsEagerInitializationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonInterceptorTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.support.ContextAwareRequestTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.support.RibbonCommandContextTest.class,
|
||||
// org.springframework.cloud.netflix.ribbon.support.RetryableStatusCodeExceptionTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilterTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.DefaultServerIntrospectorDefaultTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorPropertiesOverridesIntegrationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactoryTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.SpringClientFactoryTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonAutoConfigurationIntegrationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClientTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorOverridesIntegrationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonApplicationContextInitializerTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.okhttp.SpringRetryDisableOkHttpClientTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonResponseTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClientTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonRequestTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.okhttp.SpringRetryEnabledOkHttpClientTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonClientConfigurationIntegrationTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.RibbonDisabledTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.DefaultServerIntrospectorTests.class,
|
||||
// org.springframework.cloud.netflix.ribbon.SpringRetryDisabledTests.class,
|
||||
// org.springframework.cloud.netflix.feign.beans.FeignClientTests.class,
|
||||
// org.springframework.cloud.netflix.feign.FeignClientsRegistrarTests.class,
|
||||
// org.springframework.cloud.netflix.feign.encoding.FeignAcceptEncodingTests.class,
|
||||
// org.springframework.cloud.netflix.feign.encoding.FeignContentEncodingTests.class,
|
||||
// org.springframework.cloud.netflix.feign.FeignLoggerFactoryTests.class,
|
||||
// org.springframework.cloud.netflix.feign.FeignCompressionTests.class,
|
||||
// org.springframework.cloud.netflix.feign.EnableFeignClientsTests.class,
|
||||
// org.springframework.cloud.netflix.feign.SpringDecoderTests.class,
|
||||
// org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.class,
|
||||
// org.springframework.cloud.netflix.feign.FeignHttpClientUrlTests.class,
|
||||
// org.springframework.cloud.netflix.feign.invalid.FeignClientValidationTests.class,
|
||||
// org.springframework.cloud.netflix.feign.support.FeignHttpClientPropertiesTests.class,
|
||||
// org.springframework.cloud.netflix.feign.support.SpringMvcContractTests.class,
|
||||
// org.springframework.cloud.netflix.feign.support.SpringEncoderTests.class,
|
||||
// org.springframework.cloud.netflix.feign.FeignClientOverrideDefaultsTests.class,
|
||||
// org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClientOverrideTests.class,
|
||||
// org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientPathTests.class,
|
||||
// org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancerTests.class,
|
||||
// org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientRetryTests.class,
|
||||
// org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancerTests.class,
|
||||
// org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientTests.class,
|
||||
// org.springframework.cloud.netflix.feign.ribbon.CachingSpringLoadBalancerFactoryTests.class,
|
||||
// org.springframework.cloud.netflix.feign.valid.scanning.FeignClientEnvVarTests.class,
|
||||
// org.springframework.cloud.netflix.feign.valid.scanning.FeignClientScanningTests.class,
|
||||
// org.springframework.cloud.netflix.feign.valid.FeignOkHttpTests.class,
|
||||
// org.springframework.cloud.netflix.feign.valid.FeignClientValidationTests.class,
|
||||
// org.springframework.cloud.netflix.feign.valid.FeignClientTests.class,
|
||||
// org.springframework.cloud.netflix.feign.valid.FeignHttpClientTests.class,
|
||||
// org.springframework.cloud.netflix.feign.valid.FeignClientNotPrimaryTests.class,
|
||||
// org.springframework.cloud.netflix.feign.FeignClientFactoryTests.class,
|
||||
|
||||
})
|
||||
@Ignore
|
||||
public class AdhocTestSuite {
|
||||
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.cloud.test.ClassPathExclusions;
|
||||
import org.springframework.cloud.test.ModifiedClassPathRunner;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
@RunWith(ModifiedClassPathRunner.class)
|
||||
@ClassPathExclusions({ "micrometer-core-*" })
|
||||
public class HystrixAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
@Ignore //TODO: why does this test fail in maven, but not in IDE?
|
||||
public void contextStarts() {
|
||||
try (ConfigurableApplicationContext context = new SpringApplicationBuilder()
|
||||
.web(WebApplicationType.NONE).sources(TestApp.class).run()) {
|
||||
try {
|
||||
context.getBean("hystrixMetricsBinder");
|
||||
fail("HystrixMetricsBinder class should not be found");
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
// this is the correct case
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EnableCircuitBreaker
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
protected static class TestApp {}
|
||||
}
|
||||
-165
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.netflix.hystrix.exception.HystrixRuntimeException;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
public class HystrixCommandsTests {
|
||||
|
||||
@Test
|
||||
public void monoWorks() {
|
||||
StepVerifier.create(HystrixCommands.from(Flux.just("works"))
|
||||
.commandName("testworks")
|
||||
.toMono())
|
||||
.expectNext("works")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eagerMonoWorks() {
|
||||
StepVerifier.create(HystrixCommands.from(Mono.just("works"))
|
||||
.eager()
|
||||
.commandName("testworks")
|
||||
.toMono())
|
||||
.expectNext("works")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void monoTimesOut() {
|
||||
StepVerifier.create(HystrixCommands.from(Mono.fromCallable(() -> {
|
||||
Thread.sleep(1500);
|
||||
return "timeout";
|
||||
})).commandName("failcmd").toMono())
|
||||
.verifyError(HystrixRuntimeException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void monoFallbackWorks() {
|
||||
StepVerifier.create(HystrixCommands.from(Mono.<String>error(new Exception()))
|
||||
.commandName("failcmd")
|
||||
.fallback(Mono.just("fallback"))
|
||||
.toMono())
|
||||
.expectNext("fallback")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void monoFallbackWithExceptionWorks() {
|
||||
StepVerifier.create(HystrixCommands.from(Mono.<String>error(new IllegalStateException()))
|
||||
.commandName("failcmd")
|
||||
.fallback(throwable -> {
|
||||
if (throwable instanceof IllegalStateException) {
|
||||
return Mono.just("specificfallback");
|
||||
}
|
||||
return Mono.just("genericfallback");
|
||||
})
|
||||
.toMono())
|
||||
.expectNext("specificfallback")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fluxWorks() {
|
||||
StepVerifier.create(HystrixCommands.from( Flux.just("1", "2"))
|
||||
.commandName("multiflux")
|
||||
.toFlux())
|
||||
.expectNext("1")
|
||||
.expectNext("2")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fluxWorksDeferredRequest() {
|
||||
StepVerifier.create(HystrixCommands.from(Flux.just("1", "2"))
|
||||
.commandName("multiflux")
|
||||
.build(), 1)
|
||||
.expectNext("1")
|
||||
.thenAwait(Duration.ofSeconds(1))
|
||||
.thenRequest(1)
|
||||
.expectNext("2")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toObservableFunctionWorks() {
|
||||
StepVerifier.create(HystrixCommands.from(Flux.just("1", "2"))
|
||||
.commandName("multiflux")
|
||||
.toObservable(cmd -> cmd.toObservable())
|
||||
.build(), 1)
|
||||
.expectNext("1")
|
||||
.thenAwait(Duration.ofSeconds(1))
|
||||
.thenRequest(1)
|
||||
.verifyError();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eagerFluxWorks() {
|
||||
StepVerifier.create(HystrixCommands.from( Flux.just("1", "2"))
|
||||
.commandName("multiflux")
|
||||
.eager()
|
||||
.toFlux())
|
||||
.expectNext("1")
|
||||
.expectNext("2")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fluxTimesOut() {
|
||||
StepVerifier.create(HystrixCommands.from( Flux.from(s -> {
|
||||
try {
|
||||
Thread.sleep(1500);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})).commandName("failcmd").toFlux())
|
||||
.verifyError(HystrixRuntimeException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fluxFallbackWorks() {
|
||||
StepVerifier.create(HystrixCommands.from(Flux.<String>error(new Exception()))
|
||||
.commandName("multiflux")
|
||||
.fallback(Flux.just("a", "b"))
|
||||
.toFlux())
|
||||
.expectNext("a")
|
||||
.expectNext("b")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extendTimeout() {
|
||||
StepVerifier.create(HystrixCommands.from(Mono.fromCallable(() -> {
|
||||
Thread.sleep(1500);
|
||||
return "works";
|
||||
})).commandName("extendTimeout")
|
||||
.commandProperties(
|
||||
setter -> setter.withExecutionTimeoutInMilliseconds(2000))
|
||||
.toMono())
|
||||
.expectNext("works")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
|
||||
import io.micrometer.core.instrument.binder.MeterBinder;
|
||||
import io.micrometer.core.instrument.binder.hystrix.HystrixMetricsBinder;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Biju Kunjummen
|
||||
*/
|
||||
public class HystrixConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void nonWebAppStartsUp() {
|
||||
new ApplicationContextRunner()
|
||||
.withUserConfiguration(HystrixCircuitBreakerConfiguration.class)
|
||||
.run(c -> {
|
||||
assertThat(c).hasSingleBean(HystrixCommandAspect.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hystrixMetricsConfigured() {
|
||||
new WebApplicationContextRunner()
|
||||
.withUserConfiguration(TestApp.class)
|
||||
.run(c -> {
|
||||
assertThat(c.getBeansOfType(MeterBinder.class).values())
|
||||
.hasAtLeastOneElementOfType(HystrixMetricsBinder.class);
|
||||
});
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
protected static class TestApp {}
|
||||
}
|
||||
-195
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
import static org.springframework.cloud.netflix.test.TestAutoConfiguration.PASSWORD;
|
||||
import static org.springframework.cloud.netflix.test.TestAutoConfiguration.USER;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = HystrixOnlyApplication.class, webEnvironment = RANDOM_PORT,
|
||||
properties = {"management.endpoint.health.show-details=ALWAYS"})
|
||||
@DirtiesContext
|
||||
@ActiveProfiles("proxysecurity")
|
||||
public class HystrixOnlyTests {
|
||||
private static final String BASE_PATH = new WebEndpointProperties().getBasePath();
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
public void testNormalExecution() {
|
||||
ResponseEntity<String> res = new TestRestTemplate()
|
||||
.getForEntity("http://localhost:" + this.port + "/", String.class);
|
||||
assertEquals("incorrect response", "Hello world", res.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailureFallback() {
|
||||
ResponseEntity<String> res = new TestRestTemplate()
|
||||
.getForEntity("http://localhost:" + this.port + "/fail", String.class);
|
||||
assertEquals("incorrect fallback", "Fallback Hello world", res.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testHystrixHealth() {
|
||||
Map map = getHealth();
|
||||
assertThat(map).containsKeys("details");
|
||||
Map details = (Map) map.get("details");
|
||||
assertThat(details).containsKeys("hystrix");
|
||||
Map hystrix = (Map) details.get("hystrix");
|
||||
assertThat(hystrix).containsEntry("status", "UP");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoDiscoveryHealth() {
|
||||
Map<?, ?> map = getHealth();
|
||||
// There is explicitly no discovery, so there should be no discovery health key
|
||||
assertFalse("Incorrect existing discovery health key",
|
||||
map.containsKey("discovery"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHystrixInnerMapMetrics() {
|
||||
// We have to hit any Hystrix command before Hystrix metrics to be populated
|
||||
String url = "http://localhost:" + this.port;
|
||||
ResponseEntity<String> response = new TestRestTemplate().getForEntity(url,
|
||||
String.class);
|
||||
assertEquals("bad response code", HttpStatus.OK, response.getStatusCode());
|
||||
|
||||
// Poller takes some time to realize for new metrics
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {}
|
||||
|
||||
Map<String, List<String>> map = (Map<String, List<String>>) getMetrics();
|
||||
|
||||
assertTrue("There is no latencyTotal group key specified",
|
||||
map.get("names").contains("hystrix.latency.total"));
|
||||
assertTrue("There is no latencyExecute group key specified",
|
||||
map.get("names").contains("hystrix.latency.execution"));
|
||||
}
|
||||
|
||||
|
||||
private Map<?, ?> getMetrics() {
|
||||
return getAuthenticatedEndpoint("/metrics");
|
||||
}
|
||||
|
||||
private Map<?, ?> getHealth() {
|
||||
return getAuthenticatedEndpoint("/health");
|
||||
}
|
||||
|
||||
private Map<?, ?> getAuthenticatedEndpoint(String endpoint) {
|
||||
return new TestRestTemplate().exchange(
|
||||
"http://localhost:" + this.port + BASE_PATH + endpoint, HttpMethod.GET,
|
||||
new HttpEntity<Void>(createBasicAuthHeader(USER, PASSWORD)),
|
||||
Map.class).getBody();
|
||||
}
|
||||
|
||||
public static HttpHeaders createBasicAuthHeader(final String username,
|
||||
final String password) {
|
||||
return new HttpHeaders() {
|
||||
private static final long serialVersionUID = 1766341693637204893L;
|
||||
|
||||
{
|
||||
String auth = username + ":" + password;
|
||||
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
|
||||
String authHeader = "Basic " + new String(encodedAuth);
|
||||
this.set("Authorization", authHeader);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class Service {
|
||||
@HystrixCommand
|
||||
public String hello() {
|
||||
return "Hello world";
|
||||
}
|
||||
|
||||
@HystrixCommand(fallbackMethod = "fallback")
|
||||
public String fail() {
|
||||
throw new RuntimeException("Always fail");
|
||||
}
|
||||
|
||||
public String fallback() {
|
||||
return "Fallback Hello world";
|
||||
}
|
||||
}
|
||||
|
||||
// Don't use @SpringBootApplication because we don't want to component scan
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableCircuitBreaker
|
||||
@RestController
|
||||
class HystrixOnlyApplication {
|
||||
|
||||
@Bean
|
||||
public Service service() {
|
||||
return new Service();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Service service;
|
||||
|
||||
@RequestMapping("/")
|
||||
public String home() {
|
||||
return this.service.hello();
|
||||
}
|
||||
|
||||
@RequestMapping("/fail")
|
||||
public String fail() {
|
||||
return this.service.fail();
|
||||
}
|
||||
|
||||
}
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = HystrixStreamEndpointTests.Application.class,
|
||||
webEnvironment = WebEnvironment.RANDOM_PORT, value = {
|
||||
"spring.application.name=hystrixstreamtest" })
|
||||
@DirtiesContext
|
||||
public class HystrixStreamEndpointTests {
|
||||
private static final String BASE_PATH = new WebEndpointProperties().getBasePath();
|
||||
private static final Log log = LogFactory.getLog(HystrixStreamEndpointTests.class);
|
||||
|
||||
@LocalServerPort
|
||||
private int port = 0;
|
||||
|
||||
@Test
|
||||
public void hystrixStreamWorks() throws Exception {
|
||||
String url = "http://localhost:" + port;
|
||||
// you have to hit a Hystrix circuit breaker before the stream sends anything
|
||||
ResponseEntity<String> response = new TestRestTemplate().getForEntity(url,
|
||||
String.class);
|
||||
assertEquals("bad response code", HttpStatus.OK, response.getStatusCode());
|
||||
|
||||
URL hystrixUrl = new URL(url + BASE_PATH + "/hystrix.stream");
|
||||
|
||||
List<String> data = new ArrayList<>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
try (InputStream in = hystrixUrl.openStream()) {
|
||||
byte[] buffer = new byte[1024];
|
||||
in.read(buffer);
|
||||
data.add(new String(buffer));
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting hystrix stream, try " + i, e);
|
||||
}
|
||||
}
|
||||
|
||||
for (String item : data) {
|
||||
if (item.contains("data:")) {
|
||||
return; // test passed
|
||||
}
|
||||
}
|
||||
fail("/hystrix.stream didn't contain 'data:' was " + data);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@EnableCircuitBreaker
|
||||
protected static class Application {
|
||||
@Autowired
|
||||
Service service;
|
||||
|
||||
@Bean
|
||||
Service service() {
|
||||
return new Service();
|
||||
}
|
||||
|
||||
@RequestMapping("/")
|
||||
public String hello() {
|
||||
return service.hello();
|
||||
}
|
||||
}
|
||||
|
||||
protected static class Service {
|
||||
@HystrixCommand
|
||||
public String hello() {
|
||||
return "Hello World";
|
||||
}
|
||||
}
|
||||
}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.cloud.netflix.test.TestAutoConfiguration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest( webEnvironment = RANDOM_PORT, properties = {
|
||||
"spring.main.web-application-type=reactive",
|
||||
"spring.application.name=hystrixstreamwebfluxtest", /*"debug=true"*/ })
|
||||
@DirtiesContext
|
||||
public class HystrixWebfluxEndpointTests {
|
||||
private static final String BASE_PATH = new WebEndpointProperties().getBasePath();
|
||||
private static final Log log = LogFactory.getLog(HystrixWebfluxEndpointTests.class);
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
public void hystrixStreamWorks() {
|
||||
String url = "http://localhost:" + port;
|
||||
// you have to hit a Hystrix circuit breaker before the stream sends anything
|
||||
WebTestClient testClient = WebTestClient.bindToServer().baseUrl(url).build();
|
||||
testClient.get().uri("/").exchange().expectStatus().isOk();
|
||||
|
||||
WebClient client = WebClient.create(url);
|
||||
|
||||
Flux<String> result = client.get().uri(BASE_PATH + "/hystrix.stream")
|
||||
.accept(MediaType.TEXT_EVENT_STREAM)
|
||||
.exchange()
|
||||
.flatMapMany(res -> res.bodyToFlux(Map.class))
|
||||
.take(5)
|
||||
.filter(map -> "HystrixCommand".equals(map.get("type")))
|
||||
.map(map -> (String)map.get("type"));
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNext("HystrixCommand")
|
||||
.thenCancel()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@RestController
|
||||
@EnableCircuitBreaker
|
||||
@EnableAutoConfiguration(exclude = TestAutoConfiguration.class,
|
||||
excludeName = {"org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration",
|
||||
"org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration"})
|
||||
@SpringBootConfiguration
|
||||
protected static class Config {
|
||||
@HystrixCommand
|
||||
@RequestMapping("/")
|
||||
public String hi() {
|
||||
return "hi";
|
||||
}
|
||||
}
|
||||
}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix.security;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
*/
|
||||
@Configuration
|
||||
@SpringBootApplication
|
||||
public class HystrixSecurityApplication {
|
||||
|
||||
}
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix.security;
|
||||
|
||||
import com.netflix.hystrix.strategy.HystrixPlugins;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault;
|
||||
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
|
||||
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
|
||||
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
|
||||
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
|
||||
import org.junit.Test;
|
||||
import org.mockito.internal.util.reflection.FieldSetter;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author : ailin.zhou
|
||||
*/
|
||||
public class HystrixSecurityAutoConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void testInit() throws NoSuchFieldException, IllegalAccessException {
|
||||
|
||||
//save test context
|
||||
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
|
||||
.getEventNotifier();
|
||||
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
|
||||
.getMetricsPublisher();
|
||||
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
|
||||
.getPropertiesStrategy();
|
||||
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance()
|
||||
.getCommandExecutionHook();
|
||||
HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
|
||||
|
||||
//test
|
||||
testForMultiConcurrentStrategy();
|
||||
|
||||
//recover test context
|
||||
HystrixPlugins.reset();
|
||||
HystrixPlugins.getInstance().registerConcurrencyStrategy(concurrencyStrategy);
|
||||
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
|
||||
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
|
||||
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
|
||||
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void testForMultiConcurrentStrategy() throws IllegalAccessException, NoSuchFieldException {
|
||||
HystrixSecurityAutoConfiguration securityStrategy = new HystrixSecurityAutoConfiguration();
|
||||
|
||||
//1.existingConcurrencyStrategy is null, registeredStrategy is default
|
||||
HystrixPlugins.reset();
|
||||
securityStrategy.init();
|
||||
//result is default
|
||||
assertEquals(HystrixConcurrencyStrategyDefault.getInstance(), getOriginalInSecurityConcurrencyStrategy());
|
||||
|
||||
//2.existingConcurrencyStrategy is null, registered strategy is customized
|
||||
HystrixPlugins.reset();
|
||||
HystrixConcurrencyStrategy customized = new HystrixConcurrencyStrategy() {
|
||||
};
|
||||
HystrixPlugins.getInstance().registerConcurrencyStrategy(customized);
|
||||
securityStrategy.init();
|
||||
//result is customized
|
||||
assertEquals(customized, getOriginalInSecurityConcurrencyStrategy());
|
||||
|
||||
//3.existingConcurrencyStrategy is not null, registeredStrategy is default.
|
||||
HystrixPlugins.reset();
|
||||
HystrixConcurrencyStrategy existingConcurrencyStrategy = new HystrixConcurrencyStrategy() {
|
||||
};
|
||||
FieldSetter.setField(securityStrategy, securityStrategy.getClass().getDeclaredField("existingConcurrencyStrategy"), existingConcurrencyStrategy);
|
||||
securityStrategy.init();
|
||||
//result is existingConcurrencyStrategy
|
||||
assertEquals(existingConcurrencyStrategy, getOriginalInSecurityConcurrencyStrategy());
|
||||
|
||||
//4.existingConcurrencyStrategy is not null, registeredStrategy is customized.
|
||||
HystrixPlugins.reset();
|
||||
HystrixPlugins.getInstance().registerConcurrencyStrategy(customized);
|
||||
FieldSetter.setField(securityStrategy, securityStrategy.getClass().getDeclaredField("existingConcurrencyStrategy"), existingConcurrencyStrategy);
|
||||
securityStrategy.init();
|
||||
assertEquals(existingConcurrencyStrategy, getOriginalInSecurityConcurrencyStrategy());
|
||||
}
|
||||
|
||||
private HystrixConcurrencyStrategy getOriginalInSecurityConcurrencyStrategy() throws IllegalAccessException, NoSuchFieldException {
|
||||
HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
|
||||
Field existingConcurrencyStrategy = concurrencyStrategy.getClass().getDeclaredField("existingConcurrencyStrategy");
|
||||
existingConcurrencyStrategy.setAccessible(true);
|
||||
HystrixConcurrencyStrategy strategyInSecurityStrategy = (HystrixConcurrencyStrategy) existingConcurrencyStrategy.get(concurrencyStrategy);
|
||||
return strategyInSecurityStrategy;
|
||||
}
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix.security;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.netflix.hystrix.strategy.HystrixPlugins;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@DirtiesContext
|
||||
@SpringBootTest(classes = HystrixSecurityApplication.class)
|
||||
public class HystrixSecurityNoFeignTests {
|
||||
|
||||
@Test
|
||||
public void testSecurityConcurrencyStrategyInstalled() {
|
||||
HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
|
||||
assertThat(concurrencyStrategy).isInstanceOf(SecurityContextConcurrencyStrategy.class);
|
||||
}
|
||||
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
package org.springframework.cloud.netflix.hystrix.security.app;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
|
||||
@Component
|
||||
public class CustomConcurrenyStrategy extends HystrixConcurrencyStrategy {
|
||||
private boolean hookCalled;
|
||||
|
||||
@Override
|
||||
public <T> Callable<T> wrapCallable(Callable<T> callable) {
|
||||
this.hookCalled = true;
|
||||
|
||||
return super.wrapCallable(callable);
|
||||
}
|
||||
|
||||
public boolean isHookCalled() {
|
||||
return hookCalled;
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix.security.app;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/username")
|
||||
public class UsernameController {
|
||||
@RequestMapping
|
||||
public String getUsername(@RequestHeader String username){
|
||||
return username;
|
||||
}
|
||||
}
|
||||
-286
@@ -1,286 +0,0 @@
|
||||
package org.springframework.cloud.netflix.resttemplate;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.SocketUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.netflix.client.RetryHandler;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AvailabilityFilteringRule;
|
||||
import com.netflix.loadbalancer.BaseLoadBalancer;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.IPing;
|
||||
import com.netflix.loadbalancer.IRule;
|
||||
import com.netflix.loadbalancer.LoadBalancerBuilder;
|
||||
import com.netflix.loadbalancer.LoadBalancerStats;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import com.netflix.loadbalancer.ServerStats;
|
||||
import com.netflix.niws.client.http.HttpClientLoadBalancerErrorHandler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = RestTemplateRetryTests.Application.class, webEnvironment = RANDOM_PORT,
|
||||
properties = { "spring.application.name=resttemplatetest", "logging.level.com.netflix=DEBUG",
|
||||
"logging.level.org.springframework.cloud.netflix.resttemplate=DEBUG",
|
||||
"logging.level.com.netflix=DEBUG", "badClients.ribbon.MaxAutoRetries=25",
|
||||
"badClients.ribbon.OkToRetryOnAllOperations=true", "ribbon.http.client.enabled" })
|
||||
@DirtiesContext
|
||||
public class RestTemplateRetryTests {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(RestTemplateRetryTests.class);
|
||||
|
||||
@Autowired
|
||||
private RestTemplate testClient;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
// Force Ribbon configuration by making one call.
|
||||
this.testClient.getForObject("http://badClients/ping", Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullPointer() throws Exception {
|
||||
|
||||
LoadBalancerStats stats = LocalBadClientConfiguration.balancer
|
||||
.getLoadBalancerStats();
|
||||
ServerStats badServer1Stats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.badServer);
|
||||
ServerStats badServer2Stats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.badServer2);
|
||||
ServerStats goodServerStats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.goodServer);
|
||||
|
||||
badServer1Stats.clearSuccessiveConnectionFailureCount();
|
||||
badServer2Stats.clearSuccessiveConnectionFailureCount();
|
||||
int numCalls = 10;
|
||||
long targetConnectionCount = goodServerStats.getTotalRequestsCount() + numCalls;
|
||||
|
||||
// A null pointer should NOT trigger a circuit breaker.
|
||||
for (int index = 0; index < numCalls; index++) {
|
||||
try {
|
||||
this.testClient.getForObject("http://badClients/null", Integer.class);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
}
|
||||
}
|
||||
logServerStats(LocalBadClientConfiguration.badServer);
|
||||
logServerStats(LocalBadClientConfiguration.badServer2);
|
||||
logServerStats(LocalBadClientConfiguration.goodServer);
|
||||
|
||||
assertTrue(badServer1Stats.isCircuitBreakerTripped());
|
||||
assertTrue(badServer2Stats.isCircuitBreakerTripped());
|
||||
assertThat(targetConnectionCount).isLessThanOrEqualTo(goodServerStats.getTotalRequestsCount());
|
||||
|
||||
// Wait for any timeout thread to finish.
|
||||
|
||||
}
|
||||
|
||||
private void logServerStats(Server server) {
|
||||
LoadBalancerStats stats = LocalBadClientConfiguration.balancer
|
||||
.getLoadBalancerStats();
|
||||
ServerStats serverStats = stats.getSingleServerStat(server);
|
||||
logger.debug("Server : " + server.toString() + " : Total Count == "
|
||||
+ serverStats.getTotalRequestsCount() + ", Failure Count == "
|
||||
+ serverStats.getFailureCount() + ", Successive Connection Failure == "
|
||||
+ serverStats.getSuccessiveConnectionFailureCount()
|
||||
+ ", Circuit Breaker ? == " + serverStats.isCircuitBreakerTripped());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestRetries() {
|
||||
|
||||
LoadBalancerStats stats = LocalBadClientConfiguration.balancer
|
||||
.getLoadBalancerStats();
|
||||
ServerStats badServer1Stats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.badServer);
|
||||
ServerStats badServer2Stats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.badServer2);
|
||||
ServerStats goodServerStats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.goodServer);
|
||||
|
||||
badServer1Stats.clearSuccessiveConnectionFailureCount();
|
||||
badServer2Stats.clearSuccessiveConnectionFailureCount();
|
||||
int numCalls = 20;
|
||||
long targetConnectionCount = goodServerStats.getTotalRequestsCount() + numCalls;
|
||||
|
||||
int hits = 0;
|
||||
|
||||
for (int index = 0; index < numCalls; index++) {
|
||||
hits = this.testClient.getForObject("http://badClients/good", Integer.class);
|
||||
}
|
||||
|
||||
logServerStats(LocalBadClientConfiguration.badServer);
|
||||
logServerStats(LocalBadClientConfiguration.badServer2);
|
||||
logServerStats(LocalBadClientConfiguration.goodServer);
|
||||
|
||||
assertTrue(badServer1Stats.isCircuitBreakerTripped());
|
||||
assertTrue(badServer2Stats.isCircuitBreakerTripped());
|
||||
assertThat(targetConnectionCount).isLessThanOrEqualTo(goodServerStats.getTotalRequestsCount());
|
||||
assertThat(hits).isGreaterThanOrEqualTo(numCalls);
|
||||
logger.debug("Retry Hits: " + hits);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestRetriesWithReadTimeout() throws Exception {
|
||||
|
||||
LoadBalancerStats stats = LocalBadClientConfiguration.balancer
|
||||
.getLoadBalancerStats();
|
||||
ServerStats badServer1Stats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.badServer);
|
||||
ServerStats badServer2Stats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.badServer2);
|
||||
ServerStats goodServerStats = stats
|
||||
.getSingleServerStat(LocalBadClientConfiguration.goodServer);
|
||||
|
||||
badServer1Stats.clearSuccessiveConnectionFailureCount();
|
||||
badServer2Stats.clearSuccessiveConnectionFailureCount();
|
||||
assertTrue(!badServer1Stats.isCircuitBreakerTripped());
|
||||
assertTrue(!badServer2Stats.isCircuitBreakerTripped());
|
||||
|
||||
int hits = 0;
|
||||
|
||||
int numCalls = 15;
|
||||
for (int index = 0; index < numCalls; index++) {
|
||||
hits = this.testClient.getForObject("http://badClients/timeout",
|
||||
Integer.class);
|
||||
}
|
||||
logServerStats(LocalBadClientConfiguration.badServer);
|
||||
logServerStats(LocalBadClientConfiguration.badServer2);
|
||||
logServerStats(LocalBadClientConfiguration.goodServer);
|
||||
|
||||
assertTrue(badServer1Stats.isCircuitBreakerTripped());
|
||||
assertTrue(badServer2Stats.isCircuitBreakerTripped());
|
||||
assertTrue(!goodServerStats.isCircuitBreakerTripped());
|
||||
|
||||
// 15 + 4 timeouts. See the endpoint for timeout conditions.
|
||||
assertThat(hits).isGreaterThanOrEqualTo(numCalls + 4);
|
||||
|
||||
// Wait for any timeout thread to finish.
|
||||
Thread.sleep(600);
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@RibbonClient(name = "badClients", configuration = LocalBadClientConfiguration.class)
|
||||
public static class Application {
|
||||
|
||||
private AtomicInteger hits = new AtomicInteger(1);
|
||||
private AtomicInteger retryHits = new AtomicInteger(1);
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/ping")
|
||||
public int ping() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/good")
|
||||
public int good() {
|
||||
int lValue = this.hits.getAndIncrement();
|
||||
return lValue;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/timeout")
|
||||
public int timeout() throws Exception {
|
||||
int lValue = this.retryHits.getAndIncrement();
|
||||
|
||||
// Force the good server to have 2 consecutive errors a couple of times.
|
||||
if (lValue == 2 || lValue == 3 || lValue == 5 || lValue == 6) {
|
||||
Thread.sleep(500);
|
||||
}
|
||||
return lValue;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/null")
|
||||
public int isNull() throws Exception {
|
||||
throw new NullPointerException("Null");
|
||||
}
|
||||
|
||||
@LoadBalanced
|
||||
@Bean
|
||||
RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load balancer with fixed server list for "local" pointing to localhost
|
||||
// and some bogus servers are thrown in to test retry
|
||||
@Configuration
|
||||
static class LocalBadClientConfiguration {
|
||||
|
||||
static BaseLoadBalancer balancer;
|
||||
static Server goodServer;
|
||||
static Server badServer;
|
||||
static Server badServer2;
|
||||
|
||||
public LocalBadClientConfiguration() {
|
||||
}
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
|
||||
@Bean
|
||||
public IRule loadBalancerRule() {
|
||||
// This is a good place to try different load balancing rules and how those rules
|
||||
// behave in failure states: BestAvailableRule, WeightedResponseTimeRule, etc
|
||||
|
||||
// This rule just uses a round robin and will skip servers that are in circuit
|
||||
// breaker state.
|
||||
return new AvailabilityFilteringRule();
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
|
||||
ServerList<Server> serverList, IRule rule, IPing ping) {
|
||||
|
||||
goodServer = new Server("localhost", this.port);
|
||||
badServer = new Server("mybadhost", 10001);
|
||||
badServer2 = new Server("localhost", SocketUtils.findAvailableTcpPort());
|
||||
|
||||
balancer = LoadBalancerBuilder.newBuilder().withClientConfig(config)
|
||||
.withRule(rule).withPing(ping).buildFixedServerListLoadBalancer(
|
||||
Arrays.asList(badServer, badServer2, goodServer));
|
||||
return balancer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RetryHandler retryHandler() {
|
||||
return new OverrideRetryHandler();
|
||||
}
|
||||
|
||||
static class OverrideRetryHandler extends HttpClientLoadBalancerErrorHandler {
|
||||
public OverrideRetryHandler() {
|
||||
this.circuitRelated.add(UnknownHostException.class);
|
||||
this.retriable.add(UnknownHostException.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon.apache;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Locale;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.entity.BasicHttpEntity;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HttpClientStatusCodeExceptionTest {
|
||||
|
||||
@Test
|
||||
public void getResponse() throws Exception {
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
doReturn(new Locale("en")).when(response).getLocale();
|
||||
Header foo = new BasicHeader("foo", "bar");
|
||||
Header[] headers = new Header[]{foo};
|
||||
doReturn(headers).when(response).getAllHeaders();
|
||||
StatusLine statusLine = new BasicStatusLine(new ProtocolVersion("http", 1, 1),
|
||||
200, "Success");
|
||||
doReturn(statusLine).when(response).getStatusLine();
|
||||
BasicHttpEntity entity = new BasicHttpEntity();
|
||||
entity.setContent(new ByteArrayInputStream("foo".getBytes()));
|
||||
entity.setContentLength(3);
|
||||
doReturn(entity).when(response).getEntity();
|
||||
HttpEntity copiedEntity = HttpClientUtils.createEntity(response);
|
||||
HttpClientStatusCodeException ex = new HttpClientStatusCodeException("service", response, copiedEntity,
|
||||
new URI("https://service.com"));
|
||||
assertEquals("en", ex.getResponse().getLocale().toString());
|
||||
assertArrayEquals(headers, ex.getResponse().getAllHeaders());
|
||||
assertEquals("Success", ex.getResponse().getStatusLine().getReasonPhrase());
|
||||
assertEquals(200, ex.getResponse().getStatusLine().getStatusCode());
|
||||
assertEquals("http", ex.getResponse().getStatusLine().getProtocolVersion().getProtocol());
|
||||
assertEquals(1, ex.getResponse().getStatusLine().getProtocolVersion().getMajor());
|
||||
assertEquals(1, ex.getResponse().getStatusLine().getProtocolVersion().getMinor());
|
||||
assertEquals("foo", EntityUtils.toString(ex.getResponse().getEntity()));
|
||||
verify(response, times(1)).close();
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon.okhttp;
|
||||
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
import java.net.URI;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class OkHttpStatusCodeExceptionTest {
|
||||
|
||||
@Test
|
||||
public void getResponse() throws Exception {
|
||||
Headers headers = new Headers.Builder().add("foo", "bar").build();
|
||||
Response response = new Response.Builder().code(200).headers(headers).code(200).message("Success")
|
||||
.body(ResponseBody.create(MediaType.parse("text/plain"), "foo")).protocol(Protocol.HTTP_1_1)
|
||||
.request(new Request.Builder().url("https://service.com").build()).build();
|
||||
ResponseBody body = response.peekBody(Integer.MAX_VALUE);
|
||||
OkHttpStatusCodeException ex = new OkHttpStatusCodeException("service", response, body, new URI("https://service.com"));
|
||||
assertEquals(headers, ex.getResponse().headers());
|
||||
assertEquals(200, ex.getResponse().code());
|
||||
assertEquals("Success", ex.getResponse().message());
|
||||
assertEquals("foo", ex.getResponse().body().string());
|
||||
assertEquals(Protocol.HTTP_1_1, ex.getResponse().protocol());
|
||||
}
|
||||
}
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Configuration
|
||||
@Import({NoopDiscoveryClientAutoConfiguration.class})
|
||||
@AutoConfigureBefore(SecurityAutoConfiguration.class)
|
||||
public class TestAutoConfiguration {
|
||||
|
||||
public static final String USER = "user";
|
||||
public static final String PASSWORD = "{noop}password";
|
||||
|
||||
@Configuration
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
protected static class TestSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
|
||||
TestSecurityConfiguration() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() {
|
||||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
|
||||
manager.createUser(User.withUsername(USER).password(PASSWORD).roles("USER").build());
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// super.configure(http);
|
||||
http.antMatcher("/proxy-username")
|
||||
.httpBasic()
|
||||
.and()
|
||||
.authorizeRequests().antMatchers("/**").permitAll();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.netflix.test.TestAutoConfiguration
|
||||
@@ -1,35 +0,0 @@
|
||||
server:
|
||||
port: 9999
|
||||
compression:
|
||||
enabled: true
|
||||
min-response-size: 1024
|
||||
mime-types: application/xml,application/json
|
||||
spring:
|
||||
application:
|
||||
name: testclient
|
||||
eureka:
|
||||
server:
|
||||
enabled: false
|
||||
client:
|
||||
registerWithEureka: false
|
||||
fetchRegistry: false
|
||||
#error:
|
||||
# path: /myerror
|
||||
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
|
||||
ribbon:
|
||||
ConnectTimeout: 3001
|
||||
ReadTimeout: 60001
|
||||
foo:
|
||||
ribbon:
|
||||
ConnectTimeout: 7
|
||||
ReadTimeout: 17
|
||||
badClients:
|
||||
ribbon:
|
||||
MaxAutoRetriesNextServer: 10
|
||||
ReadTimeout: 200
|
||||
endpoints:
|
||||
health:
|
||||
sensitive: false
|
||||
hystrix:
|
||||
shareSecurityContext: true
|
||||
management.endpoints.web.exposure.include: '*'
|
||||
@@ -1,8 +0,0 @@
|
||||
create table if not exists properties (
|
||||
property_key VARCHAR(40) NOT NULL PRIMARY KEY,
|
||||
property_value VARCHAR(255) NOT NULL,
|
||||
);
|
||||
|
||||
insert into properties(property_key, property_value) values ('db.property','this is a db property');
|
||||
insert into properties(property_key, property_value) values ('db.second.property','this is another db property');
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
archaius.file.property=Static config file property
|
||||
db.second.property=It should be overridden
|
||||
@@ -1,28 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<form method="POST" enctype="multipart/form-data"
|
||||
action="/simple/file">
|
||||
File to upload: <input type="file" name="file"><br /> Name: <input
|
||||
type="text" name="name"><br /> <br /> <input type="submit"
|
||||
value="Upload"> Press here to upload the file via ribbon proxy!
|
||||
</form>
|
||||
<form method="POST" enctype="multipart/form-data"
|
||||
action="/direct/file">
|
||||
File to upload: <input type="file" name="file"><br /> Name: <input
|
||||
type="text" name="name"><br /> <br /> <input type="submit"
|
||||
value="Upload"> Press here to upload the file via direct proxy!
|
||||
</form>
|
||||
<form method="POST" enctype="multipart/form-data"
|
||||
action="/proxy/direct/file">
|
||||
File to upload: <input type="file" name="file"><br /> Name: <input
|
||||
type="text" name="name"><br /> <br /> <input type="submit"
|
||||
value="Upload"> Press here to upload the file via proxy servlet!
|
||||
</form>
|
||||
<form method="POST" enctype="multipart/form-data"
|
||||
action="/file">
|
||||
File to upload: <input type="file" name="file"><br /> Name: <input
|
||||
type="text" name="name"><br /> <br /> <input type="submit"
|
||||
value="Upload"> Press here to upload the file directly!
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,27 +5,16 @@
|
||||
<parent>
|
||||
<artifactId>spring-cloud-dependencies-parent</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<version>2.0.5.BUILD-SNAPSHOT</version>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix-dependencies</artifactId>
|
||||
<version>2.0.4.BUILD-SNAPSHOT</version>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>spring-cloud-netflix-dependencies</name>
|
||||
<description>Spring Cloud Netflix Dependencies</description>
|
||||
<properties>
|
||||
<archaius.version>0.7.6</archaius.version>
|
||||
<eureka.version>1.9.3</eureka.version>
|
||||
<hystrix.version>1.5.18</hystrix.version>
|
||||
<ribbon.version>2.2.5</ribbon.version>
|
||||
<servo.version>0.12.21</servo.version>
|
||||
<zuul.version>1.3.1</zuul.version>
|
||||
<rxjava.version>1.2.0</rxjava.version>
|
||||
<rxjava-reactive-streams.version>1.2.1</rxjava-reactive-streams.version>
|
||||
<turbine.version>1.0.0</turbine.version>
|
||||
<eureka-jersey.version>1.19.1</eureka-jersey.version>
|
||||
<xstream.version>1.4.10</xstream.version>
|
||||
<okhttp3.version>3.8.1</okhttp3.version>
|
||||
<eureka.version>2.0.0-rc.3</eureka.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@@ -34,16 +23,6 @@
|
||||
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-archaius</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-archaius</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
@@ -54,148 +33,24 @@
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-contract</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-turbine-stream</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-sidecar</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-turbine</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-turbine-stream</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-zuul</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-ribbon</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.netflix-commons</groupId>
|
||||
<artifactId>netflix-commons-util</artifactId>
|
||||
<version>0.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
<version>${archaius.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-servlet</artifactId>
|
||||
<version>${eureka-jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-core</artifactId>
|
||||
<version>${eureka-jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<version>${eureka-jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-server</artifactId>
|
||||
<version>${eureka-jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-apache-client4</artifactId>
|
||||
<version>${eureka-jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.servo</groupId>
|
||||
<artifactId>servo-core</artifactId>
|
||||
<version>${servo.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.github.vlsi.compactmap</groupId>
|
||||
<artifactId>compactmap</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
@@ -219,6 +74,10 @@
|
||||
<artifactId>eureka-core</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
@@ -253,158 +112,24 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Eureka core dep that is now optional -->
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>${xstream.version}</version>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-core-jersey3</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client-jersey3</artifactId>
|
||||
<!-- FIXME: 4.0 -->
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<groupId>aopalliance</groupId>
|
||||
<artifactId>aopalliance</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-serialization</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-metrics-event-stream</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-javanica</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-eureka</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<version>${rxjava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex</groupId>
|
||||
<artifactId>rxjava-reactive-streams</artifactId>
|
||||
<version>${rxjava-reactive-streams.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<version>${zuul.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
<version>${okhttp3.version}</version>
|
||||
</dependency>
|
||||
<!-- TODO: Move back to Eureka dependency when 1.10.17 released -->
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<profiles>
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix-eureka-client-tls-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Netflix Eureka Client TLS Tests</name>
|
||||
<description>Spring Cloud Netflix Eureka Client TLS Tests</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.retry</groupId>
|
||||
<artifactId>spring-retry</artifactId>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-test-support</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.68</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Suite.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*Test.java</exclude>
|
||||
<exclude>**/*Tests.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.test.TestSocketUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
public class AppRunner implements AutoCloseable {
|
||||
|
||||
private Class<?> appClass;
|
||||
|
||||
private Map<String, String> props;
|
||||
|
||||
private ConfigurableApplicationContext app;
|
||||
|
||||
public AppRunner(Class<?> appClass) {
|
||||
this.appClass = appClass;
|
||||
props = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
public void property(String key, String value) {
|
||||
props.put(key, value);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (app == null) {
|
||||
SpringApplicationBuilder builder = new SpringApplicationBuilder(appClass);
|
||||
builder.properties("spring.application.name=" + appClass.getName());
|
||||
builder.properties("spring.jmx.enabled=false");
|
||||
builder.properties(String.format("server.port=%d", availabeTcpPort()));
|
||||
builder.properties(props());
|
||||
|
||||
app = builder.build().run();
|
||||
}
|
||||
}
|
||||
|
||||
private int availabeTcpPort() {
|
||||
return TestSocketUtils.findAvailableTcpPort();
|
||||
}
|
||||
|
||||
private String[] props() {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
for (String key : props.keySet()) {
|
||||
String value = props.get(key);
|
||||
result.add(String.format("%s=%s", key, value));
|
||||
}
|
||||
|
||||
return result.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (app != null) {
|
||||
app.stop();
|
||||
int attempts = 5;
|
||||
while (app.isRunning() && attempts > 0) {
|
||||
attempts = attempts - 1;
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
app = null;
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigurableApplicationContext app() {
|
||||
return app;
|
||||
}
|
||||
|
||||
public String getProperty(String key) {
|
||||
return app.getEnvironment().getProperty(key);
|
||||
}
|
||||
|
||||
public <T> T getBean(Class<T> type) {
|
||||
return app.getBean(type);
|
||||
}
|
||||
|
||||
public ApplicationContext parent() {
|
||||
return app.getParent();
|
||||
}
|
||||
|
||||
public <T> Map<String, T> getParentBeans(Class<T> type) {
|
||||
return parent().getBeansOfType(type);
|
||||
}
|
||||
|
||||
public int port() {
|
||||
if (app == null) {
|
||||
throw new RuntimeException("App is not running.");
|
||||
}
|
||||
return app.getEnvironment().getProperty("server.port", Integer.class, -1);
|
||||
}
|
||||
|
||||
public String root() {
|
||||
if (app == null) {
|
||||
throw new RuntimeException("App is not running.");
|
||||
}
|
||||
|
||||
String protocol = tlsEnabled() ? "https" : "http";
|
||||
return String.format("%s://localhost:%d/", protocol, port());
|
||||
}
|
||||
|
||||
private boolean tlsEnabled() {
|
||||
return app.getEnvironment().getProperty("server.ssl.enabled", Boolean.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
stop();
|
||||
}
|
||||
|
||||
}
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
abstract class BaseCertTest {
|
||||
|
||||
private static final Log log = LogFactory.getLog(BaseCertTest.class);
|
||||
|
||||
protected static final String KEY_STORE_PASSWORD = "test-key-store-password";
|
||||
|
||||
protected static final String KEY_PASSWORD = "test-key-password";
|
||||
|
||||
protected static final String WRONG_PASSWORD = "test-wrong-password";
|
||||
|
||||
protected static File caCert;
|
||||
|
||||
protected static File wrongCaCert;
|
||||
|
||||
protected static File serverCert;
|
||||
|
||||
protected static File clientCert;
|
||||
|
||||
protected static File wrongClientCert;
|
||||
|
||||
protected BaseCertTest() {
|
||||
}
|
||||
|
||||
static EurekaServerRunner startEurekaServer(Class config) {
|
||||
EurekaServerRunner server = new EurekaServerRunner(config);
|
||||
server.enableTls();
|
||||
server.setKeyStore(serverCert, KEY_STORE_PASSWORD, "server", KEY_PASSWORD);
|
||||
server.setTrustStore(caCert, KEY_STORE_PASSWORD);
|
||||
|
||||
server.start();
|
||||
return server;
|
||||
}
|
||||
|
||||
static void stopEurekaServer(EurekaServerRunner server) {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
static EurekaClientRunner startService(EurekaServerRunner server, Class config) {
|
||||
EurekaClientRunner service = new EurekaClientRunner(config, server, "testservice");
|
||||
enableTlsClient(service);
|
||||
service.start();
|
||||
return service;
|
||||
}
|
||||
|
||||
static void stopService(EurekaClientRunner service) {
|
||||
service.stop();
|
||||
}
|
||||
|
||||
static void enableTlsClient(EurekaClientRunner runner) {
|
||||
runner.enableTls();
|
||||
runner.setKeyStore(clientCert, KEY_STORE_PASSWORD, KEY_PASSWORD);
|
||||
runner.setTrustStore(caCert, KEY_STORE_PASSWORD);
|
||||
}
|
||||
|
||||
static void waitForRegistration(Supplier<EurekaClientRunner> clientSupplier) {
|
||||
try (EurekaClientRunner client = clientSupplier.get()) {
|
||||
enableTlsClient(client);
|
||||
client.start();
|
||||
client.waitServiceViaEureka(60);
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
static void createCertificates() throws Exception {
|
||||
KeyTool tool = new KeyTool();
|
||||
|
||||
KeyAndCert ca = tool.createCA("MyCA");
|
||||
KeyAndCert server = ca.sign("server");
|
||||
KeyAndCert client = ca.sign("client");
|
||||
|
||||
caCert = saveCert(ca);
|
||||
serverCert = saveKeyAndCert(server);
|
||||
clientCert = saveKeyAndCert(client);
|
||||
|
||||
KeyAndCert wrongCa = tool.createCA("WrongCA");
|
||||
KeyAndCert wrongClient = wrongCa.sign("client");
|
||||
|
||||
wrongCaCert = saveCert(wrongCa);
|
||||
wrongClientCert = saveKeyAndCert(wrongClient);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterClass() {
|
||||
log.info("Tests finished!");
|
||||
}
|
||||
|
||||
abstract EurekaClientRunner createEurekaClient();
|
||||
|
||||
/**
|
||||
* Already proved this in waitForRegistration(). Keep this Test to express test
|
||||
* purpose explicitly.
|
||||
*/
|
||||
@Test
|
||||
void clientCertCanWork() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void noCertCannotWork() {
|
||||
try (EurekaClientRunner client = createEurekaClient()) {
|
||||
client.disableTls();
|
||||
client.start();
|
||||
assertThat(client.foundServiceViaEureka()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongCertCannotWork() {
|
||||
try (EurekaClientRunner client = createEurekaClient()) {
|
||||
enableTlsClient(client);
|
||||
client.setKeyStore(wrongClientCert);
|
||||
client.start();
|
||||
assertThat(client.foundServiceViaEureka()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongPasswordCauseFailure() {
|
||||
EurekaClientRunner client = createEurekaClient();
|
||||
enableTlsClient(client);
|
||||
client.setKeyStore(clientCert, WRONG_PASSWORD, WRONG_PASSWORD);
|
||||
Assertions.assertThrows(BeanCreationException.class, () -> {
|
||||
client.start();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void nonExistKeyStoreCauseFailure() {
|
||||
EurekaClientRunner client = createEurekaClient();
|
||||
enableTlsClient(client);
|
||||
client.setKeyStore(new File("nonExistFile"));
|
||||
Assertions.assertThrows(BeanCreationException.class, () -> {
|
||||
client.start();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongTrustStoreCannotWork() {
|
||||
try (EurekaClientRunner client = createEurekaClient()) {
|
||||
enableTlsClient(client);
|
||||
client.setTrustStore(wrongCaCert);
|
||||
client.start();
|
||||
assertThat(client.foundServiceViaEureka()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
private static File saveKeyAndCert(KeyAndCert keyCert) throws Exception {
|
||||
return saveKeyStore(keyCert.subject(), () -> keyCert.storeKeyAndCert(KEY_PASSWORD));
|
||||
}
|
||||
|
||||
private static File saveCert(KeyAndCert keyCert) throws Exception {
|
||||
return saveKeyStore(keyCert.subject(), () -> keyCert.storeCert());
|
||||
}
|
||||
|
||||
private static File saveKeyStore(String prefix, KeyStoreSupplier func) throws Exception {
|
||||
File result = File.createTempFile(prefix, ".p12");
|
||||
result.deleteOnExit();
|
||||
|
||||
try (OutputStream output = new FileOutputStream(result)) {
|
||||
KeyStore store = func.createKeyStore();
|
||||
store.store(output, KEY_STORE_PASSWORD.toCharArray());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
interface KeyStoreSupplier {
|
||||
|
||||
KeyStore createKeyStore() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
|
||||
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
public class EurekaClientRunner extends AppRunner {
|
||||
|
||||
public EurekaClientRunner(Class<?> appClass, AppRunner server) {
|
||||
super(appClass);
|
||||
|
||||
property("eureka.client.registerWithEureka", "false");
|
||||
property("eureka.client.fetchRegistry", "true");
|
||||
property("eureka.client.serviceUrl.defaultZone", server.root() + "eureka/");
|
||||
property("eureka.client.refresh.enable", "true");
|
||||
}
|
||||
|
||||
public EurekaClientRunner(Class<?> appClass, AppRunner server, String service) {
|
||||
this(appClass, server);
|
||||
property("eureka.client.registerWithEureka", "true");
|
||||
property("spring.application.name", service);
|
||||
}
|
||||
|
||||
public void enableTls() {
|
||||
property("eureka.client.tls.enabled", "true");
|
||||
}
|
||||
|
||||
public void disableTls() {
|
||||
property("eureka.client.tls.enabled", "false");
|
||||
}
|
||||
|
||||
public void setKeyStore(File keyStore, String keyStorePassword, String keyPassword) {
|
||||
property("eureka.client.tls.key-store", pathOf(keyStore));
|
||||
property("eureka.client.tls.key-store-password", keyStorePassword);
|
||||
property("eureka.client.tls.key-password", keyPassword);
|
||||
}
|
||||
|
||||
public void setKeyStore(File keyStore) {
|
||||
property("eureka.client.tls.key-store", pathOf(keyStore));
|
||||
}
|
||||
|
||||
public void setTrustStore(File trustStore, String password) {
|
||||
property("eureka.client.tls.trust-store", pathOf(trustStore));
|
||||
property("eureka.client.tls.trust-store-password", password);
|
||||
}
|
||||
|
||||
public void setTrustStore(File trustStore) {
|
||||
property("eureka.client.tls.trust-store", pathOf(trustStore));
|
||||
}
|
||||
|
||||
private String pathOf(File file) {
|
||||
return String.format("file:%s", file.getAbsolutePath());
|
||||
}
|
||||
|
||||
public void waitServiceViaEureka(int seconds) {
|
||||
assertInSeconds(() -> foundServiceViaEureka(), seconds);
|
||||
}
|
||||
|
||||
private void assertInSeconds(BooleanSupplier assertion, int seconds) {
|
||||
long start = System.currentTimeMillis();
|
||||
long limit = 1000L * seconds;
|
||||
long duration = 0;
|
||||
|
||||
do {
|
||||
if (assertion.getAsBoolean()) {
|
||||
return;
|
||||
}
|
||||
duration = System.currentTimeMillis() - start;
|
||||
Thread.yield();
|
||||
|
||||
}
|
||||
while (duration < limit);
|
||||
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
public boolean foundServiceViaEureka() {
|
||||
DiscoveryClient discovery = getBean(DiscoveryClient.class);
|
||||
return !discovery.getServices().isEmpty();
|
||||
}
|
||||
|
||||
public AbstractDiscoveryClientOptionalArgs<Void> discoveryClientOptionalArgs() {
|
||||
return this.getBean(AbstractDiscoveryClientOptionalArgs.class);
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
/**
|
||||
* We need to use a suite cause we need to first run all the Eureka Servers, then close
|
||||
* all of them. We can't run one EurekaServer, close it and then run another one, cause
|
||||
* Eureka is using static executor services that are shutdown when we close a context.
|
||||
* That means that when the new context starts we will fail cause the executor service is
|
||||
* already shutdown.
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({ EurekaClientTest.class, RestTemplateEurekaClientTest.class })
|
||||
public class EurekaClientSuite {
|
||||
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
|
||||
|
||||
public class EurekaClientTest extends BaseCertTest {
|
||||
|
||||
private static final Log log = LogFactory.getLog(EurekaClientTest.class);
|
||||
|
||||
static EurekaServerRunner server;
|
||||
|
||||
static EurekaClientRunner service;
|
||||
|
||||
@BeforeAll
|
||||
public static void setupAll() {
|
||||
server = startEurekaServer(EurekaClientTest.TestEurekaServer.class);
|
||||
service = startService(server, EurekaClientTest.TestApp.class);
|
||||
// Will use Jersey
|
||||
// FIXME: 4.0
|
||||
// assertThat(service.discoveryClientOptionalArgs())
|
||||
// .isInstanceOf(DiscoveryClient.DiscoveryClientOptionalArgs.class);
|
||||
log.info("Successfully asserted that Jersey will be used");
|
||||
waitForRegistration(() -> new EurekaClientTest().createEurekaClient());
|
||||
}
|
||||
|
||||
@Override
|
||||
EurekaClientRunner createEurekaClient() {
|
||||
return new EurekaClientRunner(TestApp.class, server);
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
public static class TestApp {
|
||||
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@EnableEurekaServer
|
||||
public static class TestEurekaServer {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class EurekaServerRunner extends AppRunner {
|
||||
|
||||
public EurekaServerRunner(Class<?> appClass) {
|
||||
super(appClass);
|
||||
|
||||
property("eureka.client.registerWithEureka", "false");
|
||||
property("eureka.client.fetchRegistry", "false");
|
||||
property("eureka.server.waitTimeInMsWhenSyncEmpty", "0");
|
||||
property("eureka.client.refresh.enable", "true");
|
||||
}
|
||||
|
||||
public void enableTls() {
|
||||
property("server.ssl.enabled", "true");
|
||||
property("server.ssl.client-auth", "need");
|
||||
}
|
||||
|
||||
public void setKeyStore(File keyStore, String keyStorePassword, String key, String keyPassword) {
|
||||
property("server.ssl.key-store", pathOf(keyStore));
|
||||
property("server.ssl.key-store-type", "PKCS12");
|
||||
property("server.ssl.key-store-password", keyStorePassword);
|
||||
property("server.ssl.key-alias", key);
|
||||
property("server.ssl.key-password", keyPassword);
|
||||
}
|
||||
|
||||
public void setTrustStore(File trustStore, String password) {
|
||||
property("server.ssl.trust-store", pathOf(trustStore));
|
||||
property("server.ssl.trust-store-type", "PKCS12");
|
||||
property("server.ssl.trust-store-password", password);
|
||||
}
|
||||
|
||||
private String pathOf(File file) {
|
||||
return String.format("file:%s", file.getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
public class KeyAndCert {
|
||||
|
||||
private KeyPair keyPair;
|
||||
|
||||
private X509Certificate certificate;
|
||||
|
||||
public KeyAndCert(KeyPair keyPair, X509Certificate certificate) {
|
||||
this.keyPair = keyPair;
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
public KeyPair keyPair() {
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
public PublicKey publicKey() {
|
||||
return keyPair.getPublic();
|
||||
}
|
||||
|
||||
public PrivateKey privateKey() {
|
||||
return keyPair.getPrivate();
|
||||
}
|
||||
|
||||
public X509Certificate certificate() {
|
||||
return certificate;
|
||||
}
|
||||
|
||||
public String subject() {
|
||||
String dn = certificate.getSubjectDN().getName();
|
||||
int index = dn.indexOf('=');
|
||||
return dn.substring(index + 1);
|
||||
}
|
||||
|
||||
public KeyAndCert sign(String subject) throws Exception {
|
||||
KeyTool tool = new KeyTool();
|
||||
return tool.signCertificate(subject, this);
|
||||
}
|
||||
|
||||
public KeyAndCert sign(KeyPair keyPair, String subject) throws Exception {
|
||||
KeyTool tool = new KeyTool();
|
||||
return tool.signCertificate(keyPair, subject, this);
|
||||
}
|
||||
|
||||
public KeyStore storeKeyAndCert(String keyPassword) throws Exception {
|
||||
KeyStore result = KeyStore.getInstance("PKCS12");
|
||||
result.load(null);
|
||||
|
||||
result.setKeyEntry(subject(), keyPair.getPrivate(), keyPassword.toCharArray(), certChain());
|
||||
return result;
|
||||
}
|
||||
|
||||
private Certificate[] certChain() {
|
||||
return new Certificate[] { certificate() };
|
||||
}
|
||||
|
||||
public KeyStore storeCert() throws Exception {
|
||||
return storeCert("PKCS12");
|
||||
}
|
||||
|
||||
public KeyStore storeCert(String storeType) throws Exception {
|
||||
KeyStore result = KeyStore.getInstance(storeType);
|
||||
result.load(null);
|
||||
|
||||
result.setCertificateEntry(subject(), certificate());
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
|
||||
import org.bouncycastle.asn1.DERSequence;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.asn1.x509.BasicConstraints;
|
||||
import org.bouncycastle.asn1.x509.Extension;
|
||||
import org.bouncycastle.asn1.x509.GeneralName;
|
||||
import org.bouncycastle.asn1.x509.GeneralNames;
|
||||
import org.bouncycastle.asn1.x509.KeyUsage;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
|
||||
public class KeyTool {
|
||||
|
||||
private static final long ONE_DAY = 1000L * 60L * 60L * 24L;
|
||||
|
||||
private static final long TEN_YEARS = ONE_DAY * 365L * 10L;
|
||||
|
||||
public KeyAndCert createCA(String ca) throws Exception {
|
||||
KeyPair keyPair = createKeyPair();
|
||||
X509Certificate certificate = createCert(keyPair, ca);
|
||||
return new KeyAndCert(keyPair, certificate);
|
||||
}
|
||||
|
||||
public KeyAndCert signCertificate(String subject, KeyAndCert signer) throws Exception {
|
||||
return signCertificate(createKeyPair(), subject, signer);
|
||||
}
|
||||
|
||||
public KeyAndCert signCertificate(KeyPair keyPair, String subject, KeyAndCert signer) throws Exception {
|
||||
X509Certificate certificate = createCert(keyPair.getPublic(), signer.privateKey(), signer.subject(), subject);
|
||||
KeyAndCert result = new KeyAndCert(keyPair, certificate);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public KeyPair createKeyPair() throws Exception {
|
||||
return createKeyPair(1024);
|
||||
}
|
||||
|
||||
public KeyPair createKeyPair(int keySize) throws Exception {
|
||||
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
|
||||
gen.initialize(keySize, new SecureRandom());
|
||||
return gen.generateKeyPair();
|
||||
}
|
||||
|
||||
public X509Certificate createCert(KeyPair keyPair, String ca) throws Exception {
|
||||
JcaX509v3CertificateBuilder builder = certBuilder(keyPair.getPublic(), ca, ca);
|
||||
builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign));
|
||||
builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true));
|
||||
|
||||
return signCert(builder, keyPair.getPrivate());
|
||||
}
|
||||
|
||||
public X509Certificate createCert(PublicKey publicKey, PrivateKey privateKey, String issuer, String subject)
|
||||
throws Exception {
|
||||
JcaX509v3CertificateBuilder builder = certBuilder(publicKey, issuer, subject);
|
||||
builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature));
|
||||
builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));
|
||||
|
||||
GeneralName[] names = new GeneralName[] { new GeneralName(GeneralName.dNSName, "localhost") };
|
||||
builder.addExtension(Extension.subjectAlternativeName, false, GeneralNames.getInstance(new DERSequence(names)));
|
||||
|
||||
return signCert(builder, privateKey);
|
||||
}
|
||||
|
||||
private JcaX509v3CertificateBuilder certBuilder(PublicKey publicKey, String issuer, String subject) {
|
||||
X500Name issuerName = new X500Name(String.format("dc=%s", issuer));
|
||||
X500Name subjectName = new X500Name(String.format("dc=%s", subject));
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
BigInteger serialNum = BigInteger.valueOf(now);
|
||||
Date notBefore = new Date(now - ONE_DAY);
|
||||
Date notAfter = new Date(now + TEN_YEARS);
|
||||
|
||||
return new JcaX509v3CertificateBuilder(issuerName, serialNum, notBefore, notAfter, subjectName, publicKey);
|
||||
}
|
||||
|
||||
private X509Certificate signCert(JcaX509v3CertificateBuilder builder, PrivateKey privateKey) throws Exception {
|
||||
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
|
||||
X509CertificateHolder holder = builder.build(signer);
|
||||
|
||||
return new JcaX509CertificateConverter().getCertificate(holder);
|
||||
}
|
||||
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class RestTemplateEurekaClientTest extends BaseCertTest {
|
||||
|
||||
private static final Log log = LogFactory.getLog(RestTemplateEurekaClientTest.class);
|
||||
|
||||
private static EurekaServerRunner server;
|
||||
|
||||
private static EurekaClientRunner service;
|
||||
|
||||
@BeforeAll
|
||||
public static void setupAll() {
|
||||
server = startEurekaServer(RestTemplateEurekaClientTest.RestTemplateTestEurekaServer.class);
|
||||
service = startService(server, RestTemplateEurekaClientTest.RestTemplateTestApp.class);
|
||||
// Will use RestTemplate
|
||||
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
|
||||
log.info("Successfully asserted that RestTemplate will be used");
|
||||
waitForRegistration(() -> new RestTemplateEurekaClientTest().createEurekaClient());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDownAll() {
|
||||
stopService(service);
|
||||
stopEurekaServer(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
EurekaClientRunner createEurekaClient() {
|
||||
return new EurekaClientRunner(RestTemplateTestApp.class, server);
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
public static class RestTemplateTestApp {
|
||||
|
||||
// Want to force reusing exactly the same bean as on production without excluding
|
||||
// jersey from the classpath
|
||||
@Bean
|
||||
public RestTemplateDiscoveryClientOptionalArgs forceRestTemplateDiscoveryClientOptionalArgs(
|
||||
TlsProperties tlsProperties, DiscoveryClientOptionalArgsConfiguration configuration,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier)
|
||||
throws GeneralSecurityException, IOException {
|
||||
return configuration.restTemplateDiscoveryClientOptionalArgs(tlsProperties,
|
||||
eurekaClientHttpRequestFactorySupplier);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@EnableEurekaServer
|
||||
public static class RestTemplateTestEurekaServer {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>2.0.4.BUILD-SNAPSHOT</version>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
|
||||
@@ -14,7 +15,7 @@
|
||||
<description>Spring Cloud Netflix Eureka Client</description>
|
||||
<properties>
|
||||
<!-- Why do I need this now? -->
|
||||
<maven.javadoc.failOnError>false</maven.javadoc.failOnError>
|
||||
<maven.javadoc.failOnError>false</maven.javadoc.failOnError>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -28,12 +29,8 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-ribbon</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -44,12 +41,16 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-loadbalancer</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
@@ -62,51 +63,15 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- Eureka core deps that are now optional -->
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-apache-client4</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-eureka</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
@@ -117,6 +82,11 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-test-support</artifactId>
|
||||
@@ -126,6 +96,17 @@
|
||||
<groupId>org.springframework.retry</groupId>
|
||||
<artifactId>spring-retry</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+26
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,13 +20,6 @@ import java.lang.reflect.Field;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
@@ -35,31 +28,41 @@ import com.netflix.discovery.DiscoveryClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Subclass of {@link DiscoveryClient} that sends a {@link HeartbeatEvent} when
|
||||
* {@link CloudEurekaClient#onCacheRefreshed()} is called.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class CloudEurekaClient extends DiscoveryClient {
|
||||
|
||||
private static final Log log = LogFactory.getLog(CloudEurekaClient.class);
|
||||
|
||||
private final AtomicLong cacheRefreshedCount = new AtomicLong(0);
|
||||
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
private Field eurekaTransportField;
|
||||
|
||||
private ApplicationInfoManager applicationInfoManager;
|
||||
|
||||
private AtomicReference<EurekaHttpClient> eurekaHttpClient = new AtomicReference<>();
|
||||
|
||||
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager,
|
||||
EurekaClientConfig config, ApplicationEventPublisher publisher) {
|
||||
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig config,
|
||||
ApplicationEventPublisher publisher) {
|
||||
this(applicationInfoManager, config, null, publisher);
|
||||
}
|
||||
|
||||
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager,
|
||||
EurekaClientConfig config,
|
||||
AbstractDiscoveryClientOptionalArgs<?> args,
|
||||
ApplicationEventPublisher publisher) {
|
||||
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig config,
|
||||
AbstractDiscoveryClientOptionalArgs<?> args, ApplicationEventPublisher publisher) {
|
||||
super(applicationInfoManager, config, args);
|
||||
this.applicationInfoManager = applicationInfoManager;
|
||||
this.publisher = publisher;
|
||||
@@ -88,10 +91,13 @@ public class CloudEurekaClient extends DiscoveryClient {
|
||||
if (this.eurekaHttpClient.get() == null) {
|
||||
try {
|
||||
Object eurekaTransport = this.eurekaTransportField.get(this);
|
||||
Field registrationClientField = ReflectionUtils.findField(eurekaTransport.getClass(), "registrationClient");
|
||||
Field registrationClientField = ReflectionUtils.findField(eurekaTransport.getClass(),
|
||||
"registrationClient");
|
||||
ReflectionUtils.makeAccessible(registrationClientField);
|
||||
this.eurekaHttpClient.compareAndSet(null, (EurekaHttpClient) registrationClientField.get(eurekaTransport));
|
||||
} catch (IllegalAccessException e) {
|
||||
this.eurekaHttpClient.compareAndSet(null,
|
||||
(EurekaHttpClient) registrationClientField.get(eurekaTransport));
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
log.error("error getting EurekaHttpClient", e);
|
||||
}
|
||||
}
|
||||
@@ -106,10 +112,12 @@ public class CloudEurekaClient extends DiscoveryClient {
|
||||
protected void onCacheRefreshed() {
|
||||
super.onCacheRefreshed();
|
||||
|
||||
if (this.cacheRefreshedCount != null) { //might be called during construction and will be null
|
||||
if (this.cacheRefreshedCount != null) { // might be called during construction and
|
||||
// will be null
|
||||
long newCount = this.cacheRefreshedCount.incrementAndGet();
|
||||
log.trace("onCacheRefreshed called with count: " + newCount);
|
||||
this.publisher.publishEvent(new HeartbeatEvent(this, newCount));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,11 @@ import com.netflix.appinfo.InstanceInfo;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface CloudEurekaInstanceConfig extends EurekaInstanceConfig {
|
||||
|
||||
void setNonSecurePort(int port);
|
||||
|
||||
void setSecurePort(int securePort);
|
||||
|
||||
InstanceInfo.InstanceStatus getInitialStatus();
|
||||
|
||||
}
|
||||
|
||||
+42
-41
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Gregor Zurowski
|
||||
@@ -64,8 +64,7 @@ public class CloudEurekaTransportConfig implements EurekaTransportConfig {
|
||||
return sessionedClientReconnectIntervalSeconds;
|
||||
}
|
||||
|
||||
public void setSessionedClientReconnectIntervalSeconds(
|
||||
int sessionedClientReconnectIntervalSeconds) {
|
||||
public void setSessionedClientReconnectIntervalSeconds(int sessionedClientReconnectIntervalSeconds) {
|
||||
this.sessionedClientReconnectIntervalSeconds = sessionedClientReconnectIntervalSeconds;
|
||||
}
|
||||
|
||||
@@ -73,8 +72,7 @@ public class CloudEurekaTransportConfig implements EurekaTransportConfig {
|
||||
return retryableClientQuarantineRefreshPercentage;
|
||||
}
|
||||
|
||||
public void setRetryableClientQuarantineRefreshPercentage(
|
||||
double retryableClientQuarantineRefreshPercentage) {
|
||||
public void setRetryableClientQuarantineRefreshPercentage(double retryableClientQuarantineRefreshPercentage) {
|
||||
this.retryableClientQuarantineRefreshPercentage = retryableClientQuarantineRefreshPercentage;
|
||||
}
|
||||
|
||||
@@ -82,8 +80,7 @@ public class CloudEurekaTransportConfig implements EurekaTransportConfig {
|
||||
return bootstrapResolverRefreshIntervalSeconds;
|
||||
}
|
||||
|
||||
public void setBootstrapResolverRefreshIntervalSeconds(
|
||||
int bootstrapResolverRefreshIntervalSeconds) {
|
||||
public void setBootstrapResolverRefreshIntervalSeconds(int bootstrapResolverRefreshIntervalSeconds) {
|
||||
this.bootstrapResolverRefreshIntervalSeconds = bootstrapResolverRefreshIntervalSeconds;
|
||||
}
|
||||
|
||||
@@ -162,50 +159,54 @@ public class CloudEurekaTransportConfig implements EurekaTransportConfig {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
CloudEurekaTransportConfig that = (CloudEurekaTransportConfig) o;
|
||||
return sessionedClientReconnectIntervalSeconds == that.sessionedClientReconnectIntervalSeconds &&
|
||||
Double.compare(retryableClientQuarantineRefreshPercentage, that.retryableClientQuarantineRefreshPercentage) == 0 &&
|
||||
bootstrapResolverRefreshIntervalSeconds == that.bootstrapResolverRefreshIntervalSeconds &&
|
||||
applicationsResolverDataStalenessThresholdSeconds == that.applicationsResolverDataStalenessThresholdSeconds &&
|
||||
asyncResolverRefreshIntervalMs == that.asyncResolverRefreshIntervalMs &&
|
||||
asyncResolverWarmUpTimeoutMs == that.asyncResolverWarmUpTimeoutMs &&
|
||||
asyncExecutorThreadPoolSize == that.asyncExecutorThreadPoolSize &&
|
||||
Objects.equals(readClusterVip, that.readClusterVip) &&
|
||||
Objects.equals(writeClusterVip, that.writeClusterVip) &&
|
||||
bootstrapResolverForQuery == that.bootstrapResolverForQuery &&
|
||||
Objects.equals(bootstrapResolverStrategy, that.bootstrapResolverStrategy) &&
|
||||
applicationsResolverUseIp == that.applicationsResolverUseIp;
|
||||
return sessionedClientReconnectIntervalSeconds == that.sessionedClientReconnectIntervalSeconds
|
||||
&& Double.compare(retryableClientQuarantineRefreshPercentage,
|
||||
that.retryableClientQuarantineRefreshPercentage) == 0
|
||||
&& bootstrapResolverRefreshIntervalSeconds == that.bootstrapResolverRefreshIntervalSeconds
|
||||
&& applicationsResolverDataStalenessThresholdSeconds == that.applicationsResolverDataStalenessThresholdSeconds
|
||||
&& asyncResolverRefreshIntervalMs == that.asyncResolverRefreshIntervalMs
|
||||
&& asyncResolverWarmUpTimeoutMs == that.asyncResolverWarmUpTimeoutMs
|
||||
&& asyncExecutorThreadPoolSize == that.asyncExecutorThreadPoolSize
|
||||
&& Objects.equals(readClusterVip, that.readClusterVip)
|
||||
&& Objects.equals(writeClusterVip, that.writeClusterVip)
|
||||
&& bootstrapResolverForQuery == that.bootstrapResolverForQuery
|
||||
&& Objects.equals(bootstrapResolverStrategy, that.bootstrapResolverStrategy)
|
||||
&& applicationsResolverUseIp == that.applicationsResolverUseIp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sessionedClientReconnectIntervalSeconds,
|
||||
retryableClientQuarantineRefreshPercentage,
|
||||
bootstrapResolverRefreshIntervalSeconds,
|
||||
applicationsResolverDataStalenessThresholdSeconds,
|
||||
asyncResolverRefreshIntervalMs, asyncResolverWarmUpTimeoutMs,
|
||||
asyncExecutorThreadPoolSize, readClusterVip, writeClusterVip,
|
||||
bootstrapResolverForQuery, bootstrapResolverStrategy,
|
||||
return Objects.hash(sessionedClientReconnectIntervalSeconds, retryableClientQuarantineRefreshPercentage,
|
||||
bootstrapResolverRefreshIntervalSeconds, applicationsResolverDataStalenessThresholdSeconds,
|
||||
asyncResolverRefreshIntervalMs, asyncResolverWarmUpTimeoutMs, asyncExecutorThreadPoolSize,
|
||||
readClusterVip, writeClusterVip, bootstrapResolverForQuery, bootstrapResolverStrategy,
|
||||
applicationsResolverUseIp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("CloudEurekaTransportConfig{")
|
||||
.append("sessionedClientReconnectIntervalSeconds=").append(sessionedClientReconnectIntervalSeconds).append(", ")
|
||||
.append("retryableClientQuarantineRefreshPercentage=").append(retryableClientQuarantineRefreshPercentage).append(", ")
|
||||
.append("bootstrapResolverRefreshIntervalSeconds=").append(bootstrapResolverRefreshIntervalSeconds).append(", ")
|
||||
.append("applicationsResolverDataStalenessThresholdSeconds=").append(applicationsResolverDataStalenessThresholdSeconds).append(", ")
|
||||
return new StringBuilder("CloudEurekaTransportConfig{").append("sessionedClientReconnectIntervalSeconds=")
|
||||
.append(sessionedClientReconnectIntervalSeconds).append(", ")
|
||||
.append("retryableClientQuarantineRefreshPercentage=")
|
||||
.append(retryableClientQuarantineRefreshPercentage).append(", ")
|
||||
.append("bootstrapResolverRefreshIntervalSeconds=").append(bootstrapResolverRefreshIntervalSeconds)
|
||||
.append(", ").append("applicationsResolverDataStalenessThresholdSeconds=")
|
||||
.append(applicationsResolverDataStalenessThresholdSeconds).append(", ")
|
||||
.append("asyncResolverRefreshIntervalMs=").append(asyncResolverRefreshIntervalMs).append(", ")
|
||||
.append("asyncResolverWarmUpTimeoutMs=").append(asyncResolverWarmUpTimeoutMs).append(", ")
|
||||
.append("asyncExecutorThreadPoolSize=").append(asyncExecutorThreadPoolSize).append(", ")
|
||||
.append("readClusterVip='").append(readClusterVip).append("', ")
|
||||
.append("writeClusterVip='").append(writeClusterVip).append("', ")
|
||||
.append("bootstrapResolverForQuery=").append(bootstrapResolverForQuery).append(", ")
|
||||
.append("bootstrapResolverStrategy='").append(bootstrapResolverStrategy).append("', ")
|
||||
.append("applicationsResolverUseIp=").append(applicationsResolverUseIp).append(", ").append("}")
|
||||
.toString();
|
||||
.append("readClusterVip='").append(readClusterVip).append("', ").append("writeClusterVip='")
|
||||
.append(writeClusterVip).append("', ").append("bootstrapResolverForQuery=")
|
||||
.append(bootstrapResolverForQuery).append(", ").append("bootstrapResolverStrategy='")
|
||||
.append(bootstrapResolverStrategy).append("', ").append("applicationsResolverUseIp=")
|
||||
.append(applicationsResolverUseIp).append(", ").append("}").toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
+89
-108
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,13 +50,10 @@ import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.client.CommonsClientAutoConfiguration;
|
||||
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.actuator.HasFeatures;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
|
||||
import org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScope;
|
||||
import org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadata;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvider;
|
||||
@@ -68,7 +65,6 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -83,19 +79,18 @@ import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceI
|
||||
* @author Ryan Baxter
|
||||
* @author Daniel Lavoie
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author Tim Ysewyn
|
||||
*/
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass(EurekaClientConfig.class)
|
||||
@Import(DiscoveryClientOptionalArgsConfiguration.class)
|
||||
@ConditionalOnBean(EurekaDiscoveryClientConfiguration.Marker.class)
|
||||
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
|
||||
@ConditionalOnDiscoveryEnabled
|
||||
@AutoConfigureBefore({NoopDiscoveryClientAutoConfiguration.class,
|
||||
CommonsClientAutoConfiguration.class, ServiceRegistryAutoConfiguration.class})
|
||||
@AutoConfigureAfter(name = {"org.springframework.cloud.autoconfigure.RefreshAutoConfiguration",
|
||||
@AutoConfigureBefore({ CommonsClientAutoConfiguration.class, ServiceRegistryAutoConfiguration.class })
|
||||
@AutoConfigureAfter(name = { "org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration",
|
||||
"org.springframework.cloud.autoconfigure.RefreshAutoConfiguration",
|
||||
"org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration",
|
||||
"org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration"})
|
||||
"org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration" })
|
||||
public class EurekaClientAutoConfiguration {
|
||||
|
||||
private ConfigurableEnvironment env;
|
||||
@@ -112,13 +107,7 @@ public class EurekaClientAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = EurekaClientConfig.class, search = SearchStrategy.CURRENT)
|
||||
public EurekaClientConfigBean eurekaClientConfigBean(ConfigurableEnvironment env) {
|
||||
EurekaClientConfigBean client = new EurekaClientConfigBean();
|
||||
if ("bootstrap".equals(this.env.getProperty("spring.config.name"))) {
|
||||
// We don't register during bootstrap by default, but there will be another
|
||||
// chance later.
|
||||
client.setRegisterWithEureka(false);
|
||||
}
|
||||
return client;
|
||||
return new EurekaClientConfigBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -136,22 +125,21 @@ public class EurekaClientAutoConfiguration {
|
||||
public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils,
|
||||
ManagementMetadataProvider managementMetadataProvider) {
|
||||
String hostname = getProperty("eureka.instance.hostname");
|
||||
boolean preferIpAddress = Boolean
|
||||
.parseBoolean(getProperty("eureka.instance.prefer-ip-address"));
|
||||
boolean preferIpAddress = Boolean.parseBoolean(getProperty("eureka.instance.prefer-ip-address"));
|
||||
String ipAddress = getProperty("eureka.instance.ip-address");
|
||||
boolean isSecurePortEnabled = Boolean
|
||||
.parseBoolean(getProperty("eureka.instance.secure-port-enabled"));
|
||||
boolean isSecurePortEnabled = Boolean.parseBoolean(getProperty("eureka.instance.secure-port-enabled"));
|
||||
|
||||
String serverContextPath = env.getProperty("server.context-path", "/");
|
||||
int serverPort = Integer
|
||||
.valueOf(env.getProperty("server.port", env.getProperty("port", "8080")));
|
||||
String serverContextPath = env.getProperty("server.servlet.context-path", "/");
|
||||
int serverPort = Integer.parseInt(env.getProperty("server.port", env.getProperty("port", "8080")));
|
||||
|
||||
Integer managementPort = env
|
||||
.getProperty("management.server.port", Integer.class); // nullable. should be wrapped into optional
|
||||
String managementContextPath = env
|
||||
.getProperty("management.server.servlet.context-path"); // nullable. should be wrapped into optional
|
||||
Integer jmxPort = env
|
||||
.getProperty("com.sun.management.jmxremote.port", Integer.class); //nullable
|
||||
Integer managementPort = env.getProperty("management.server.port", Integer.class);
|
||||
|
||||
String managementContextPath = env.getProperty("management.server.servlet.context-path");
|
||||
if (!StringUtils.hasText(managementContextPath)) {
|
||||
managementContextPath = env.getProperty("management.server.base-path");
|
||||
}
|
||||
|
||||
Integer jmxPort = env.getProperty("com.sun.management.jmxremote.port", Integer.class);
|
||||
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
|
||||
|
||||
instance.setNonSecurePort(serverPort);
|
||||
@@ -179,8 +167,8 @@ public class EurekaClientAutoConfiguration {
|
||||
instance.setHealthCheckUrlPath(healthCheckUrlPath);
|
||||
}
|
||||
|
||||
ManagementMetadata metadata = managementMetadataProvider.get(instance, serverPort,
|
||||
serverContextPath, managementContextPath, managementPort);
|
||||
ManagementMetadata metadata = managementMetadataProvider.get(instance, serverPort, serverContextPath,
|
||||
managementContextPath, managementPort);
|
||||
|
||||
if (metadata != null) {
|
||||
instance.setStatusPageUrl(metadata.getStatusPageUrl());
|
||||
@@ -189,20 +177,15 @@ public class EurekaClientAutoConfiguration {
|
||||
instance.setSecureHealthCheckUrl(metadata.getSecureHealthCheckUrl());
|
||||
}
|
||||
Map<String, String> metadataMap = instance.getMetadataMap();
|
||||
if (metadataMap.get("management.port") == null) {
|
||||
metadataMap.put("management.port", String
|
||||
.valueOf(metadata.getManagementPort()));
|
||||
}
|
||||
metadataMap.computeIfAbsent("management.port", k -> String.valueOf(metadata.getManagementPort()));
|
||||
}
|
||||
else {
|
||||
//without the metadata the status and health check URLs will not be set
|
||||
//and the status page and health check url paths will not include the
|
||||
//context path so set them here
|
||||
// without the metadata the status and health check URLs will not be set
|
||||
// and the status page and health check url paths will not include the
|
||||
// context path so set them here
|
||||
if (StringUtils.hasText(managementContextPath)) {
|
||||
instance.setHealthCheckUrlPath(managementContextPath + instance
|
||||
.getHealthCheckUrlPath());
|
||||
instance.setStatusPageUrlPath(managementContextPath + instance
|
||||
.getStatusPageUrlPath());
|
||||
instance.setHealthCheckUrlPath(managementContextPath + instance.getHealthCheckUrlPath());
|
||||
instance.setStatusPageUrlPath(managementContextPath + instance.getStatusPageUrlPath());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,54 +200,34 @@ public class EurekaClientAutoConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {
|
||||
return new EurekaDiscoveryClient(config, client);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EurekaServiceRegistry eurekaServiceRegistry() {
|
||||
return new EurekaServiceRegistry();
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// @ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
// @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
// public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient, CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager, ObjectProvider<HealthCheckHandler> healthCheckHandler) {
|
||||
// return EurekaRegistration.builder(instanceConfig)
|
||||
// .with(applicationInfoManager)
|
||||
// .with(eurekaClient)
|
||||
// .with(healthCheckHandler)
|
||||
// .build();
|
||||
// }
|
||||
// @Bean
|
||||
// @ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
// @ConditionalOnProperty(value =
|
||||
// "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
// public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient,
|
||||
// CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager
|
||||
// applicationInfoManager, ObjectProvider<HealthCheckHandler> healthCheckHandler) {
|
||||
// return EurekaRegistration.builder(instanceConfig)
|
||||
// .with(applicationInfoManager)
|
||||
// .with(eurekaClient)
|
||||
// .with(healthCheckHandler)
|
||||
// .build();
|
||||
// }
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry registry,
|
||||
EurekaRegistration registration) {
|
||||
public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context,
|
||||
EurekaServiceRegistry registry, EurekaRegistration registration) {
|
||||
return new EurekaAutoServiceRegistration(context, registry, registration);
|
||||
}
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Conditional(OnMissingRefreshScopeCondition.class)
|
||||
@interface ConditionalOnMissingRefreshScope {
|
||||
|
||||
}
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ConditionalOnClass(RefreshScope.class)
|
||||
@ConditionalOnBean(RefreshAutoConfiguration.class)
|
||||
@ConditionalOnProperty(value = "eureka.client.refresh.enable", havingValue = "true", matchIfMissing = true)
|
||||
@interface ConditionalOnRefreshScope {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingRefreshScope
|
||||
protected static class EurekaClientConfiguration {
|
||||
|
||||
@@ -277,14 +240,12 @@ public class EurekaClientAutoConfiguration {
|
||||
@Bean(destroyMethod = "shutdown")
|
||||
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
|
||||
public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config) {
|
||||
return new CloudEurekaClient(manager, config, this.optionalArgs,
|
||||
this.context);
|
||||
return new CloudEurekaClient(manager, config, this.optionalArgs, this.context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT)
|
||||
public ApplicationInfoManager eurekaApplicationInfoManager(
|
||||
EurekaInstanceConfig config) {
|
||||
public ApplicationInfoManager eurekaApplicationInfoManager(EurekaInstanceConfig config) {
|
||||
InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
|
||||
return new ApplicationInfoManager(config, instanceInfo);
|
||||
}
|
||||
@@ -293,18 +254,15 @@ public class EurekaClientAutoConfiguration {
|
||||
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient,
|
||||
CloudEurekaInstanceConfig instanceConfig,
|
||||
ApplicationInfoManager applicationInfoManager,
|
||||
CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager,
|
||||
@Autowired(required = false) ObjectProvider<HealthCheckHandler> healthCheckHandler) {
|
||||
return EurekaRegistration.builder(instanceConfig)
|
||||
.with(applicationInfoManager)
|
||||
.with(eurekaClient)
|
||||
.with(healthCheckHandler)
|
||||
.build();
|
||||
return EurekaRegistration.builder(instanceConfig).with(applicationInfoManager).with(eurekaClient)
|
||||
.with(healthCheckHandler).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnRefreshScope
|
||||
protected static class RefreshableEurekaClientConfiguration {
|
||||
|
||||
@@ -318,12 +276,15 @@ public class EurekaClientAutoConfiguration {
|
||||
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
|
||||
@org.springframework.cloud.context.config.annotation.RefreshScope
|
||||
@Lazy
|
||||
public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config, EurekaInstanceConfig instance,
|
||||
@Autowired(required = false) HealthCheckHandler healthCheckHandler) {
|
||||
//If we use the proxy of the ApplicationInfoManager we could run into a problem
|
||||
//when shutdown is called on the CloudEurekaClient where the ApplicationInfoManager bean is
|
||||
//requested but wont be allowed because we are shutting down. To avoid this we use the
|
||||
//object directly.
|
||||
public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config,
|
||||
EurekaInstanceConfig instance, @Autowired(required = false) HealthCheckHandler healthCheckHandler) {
|
||||
// If we use the proxy of the ApplicationInfoManager we could run into a
|
||||
// problem
|
||||
// when shutdown is called on the CloudEurekaClient where the
|
||||
// ApplicationInfoManager bean is
|
||||
// requested but wont be allowed because we are shutting down. To avoid this
|
||||
// we use the
|
||||
// object directly.
|
||||
ApplicationInfoManager appManager;
|
||||
if (AopUtils.isAopProxy(manager)) {
|
||||
appManager = ProxyUtils.getTargetObject(manager);
|
||||
@@ -351,41 +312,59 @@ public class EurekaClientAutoConfiguration {
|
||||
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient,
|
||||
CloudEurekaInstanceConfig instanceConfig,
|
||||
ApplicationInfoManager applicationInfoManager,
|
||||
CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager,
|
||||
@Autowired(required = false) ObjectProvider<HealthCheckHandler> healthCheckHandler) {
|
||||
return EurekaRegistration.builder(instanceConfig)
|
||||
.with(applicationInfoManager)
|
||||
.with(eurekaClient)
|
||||
.with(healthCheckHandler)
|
||||
.build();
|
||||
return EurekaRegistration.builder(instanceConfig).with(applicationInfoManager).with(eurekaClient)
|
||||
.with(healthCheckHandler).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Conditional(OnMissingRefreshScopeCondition.class)
|
||||
@interface ConditionalOnMissingRefreshScope {
|
||||
|
||||
}
|
||||
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ConditionalOnClass(RefreshScope.class)
|
||||
@ConditionalOnBean(RefreshAutoConfiguration.class)
|
||||
@ConditionalOnProperty(value = "eureka.client.refresh.enable", havingValue = "true", matchIfMissing = true)
|
||||
@interface ConditionalOnRefreshScope {
|
||||
|
||||
}
|
||||
|
||||
private static class OnMissingRefreshScopeCondition extends AnyNestedCondition {
|
||||
|
||||
public OnMissingRefreshScopeCondition() {
|
||||
OnMissingRefreshScopeCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnMissingClass("org.springframework.cloud.context.scope.refresh.RefreshScope")
|
||||
static class MissingClass {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean(RefreshAutoConfiguration.class)
|
||||
static class MissingScope {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(value = "eureka.client.refresh.enable", havingValue = "false")
|
||||
static class OnPropertyDisabled {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(Health.class)
|
||||
protected static class EurekaHealthIndicatorConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnEnabledHealthIndicator("eureka")
|
||||
@@ -393,5 +372,7 @@ public class EurekaClientAutoConfiguration {
|
||||
EurekaInstanceConfig instanceConfig, EurekaClientConfig clientConfig) {
|
||||
return new EurekaHealthIndicator(eurekaClient, instanceConfig, clientConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+173
-172
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
@@ -22,30 +22,42 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.appinfo.EurekaAccept;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
|
||||
import org.apache.hc.client5.http.classic.HttpClient;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.springframework.cloud.netflix.eureka.EurekaConstants.DEFAULT_PREFIX;
|
||||
|
||||
/**
|
||||
* Eureka client configuration bean.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Gregor Zurowski
|
||||
*/
|
||||
@ConfigurationProperties(EurekaClientConfigBean.PREFIX)
|
||||
public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
public class EurekaClientConfigBean implements EurekaClientConfig, Ordered {
|
||||
|
||||
/**
|
||||
* Default prefix for Eureka client config properties.
|
||||
*/
|
||||
public static final String PREFIX = "eureka.client";
|
||||
|
||||
public static final String DEFAULT_URL = "http://localhost:8761" + DEFAULT_PREFIX
|
||||
+ "/";
|
||||
/**
|
||||
* Default Eureka URL.
|
||||
*/
|
||||
public static final String DEFAULT_URL = "http://localhost:8761" + DEFAULT_PREFIX + "/";
|
||||
|
||||
/**
|
||||
* Default availability zone if none is resolved based on region.
|
||||
*/
|
||||
public static final String DEFAULT_ZONE = "defaultZone";
|
||||
|
||||
private static final int MINUTES = 60;
|
||||
@@ -75,7 +87,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
/**
|
||||
* Indicates how long initially (in seconds) to replicate instance info to the eureka
|
||||
* server
|
||||
* server.
|
||||
*/
|
||||
private int initialInstanceInfoReplicationIntervalSeconds = 40;
|
||||
|
||||
@@ -115,14 +127,14 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
/**
|
||||
* Indicates how long to wait (in seconds) before a connection to eureka server needs
|
||||
* to timeout. Note that the connections in the client are pooled by
|
||||
* org.apache.http.client.HttpClient and this setting affects the actual connection
|
||||
* creation and also the wait time to get the connection from the pool.
|
||||
* {@link HttpClient} and this setting affects the actual connection creation and also
|
||||
* the wait time to get the connection from the pool.
|
||||
*/
|
||||
private int eurekaServerConnectTimeoutSeconds = 5;
|
||||
|
||||
/**
|
||||
* Gets the name of the implementation which implements BackupRegistry to fetch the
|
||||
* registry information as a fall back option for only the first time when the eureka
|
||||
* registry information as a fallback option for only the first time when the eureka
|
||||
* client starts.
|
||||
*
|
||||
* This may be needed for applications which needs additional resiliency for registry
|
||||
@@ -190,7 +202,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
*
|
||||
* In the AWS environment, it is recommended that the values is 30 seconds or less,
|
||||
* since the firewall cleans up the connection information after a few mins leaving
|
||||
* the connection hanging in limbo
|
||||
* the connection hanging in limbo.
|
||||
*/
|
||||
private int eurekaConnectionIdleTimeoutSeconds = 30;
|
||||
|
||||
@@ -201,7 +213,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
private String registryRefreshSingleVipAddress;
|
||||
|
||||
/**
|
||||
* The thread pool size for the heartbeatExecutor to initialise with
|
||||
* The thread pool size for the heartbeatExecutor to initialise with.
|
||||
*/
|
||||
private int heartbeatExecutorThreadPoolSize = 2;
|
||||
|
||||
@@ -212,7 +224,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
private int heartbeatExecutorExponentialBackOffBound = 10;
|
||||
|
||||
/**
|
||||
* The thread pool size for the cacheRefreshExecutor to initialise with
|
||||
* The thread pool size for the cacheRefreshExecutor to initialise with.
|
||||
*/
|
||||
private int cacheRefreshExecutorThreadPoolSize = 2;
|
||||
|
||||
@@ -348,8 +360,8 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
private String dollarReplacement = "_-";
|
||||
|
||||
/**
|
||||
* Get a replacement string for underscore sign <code>_</code> during
|
||||
* serializing/deserializing information in eureka server.
|
||||
* Get a replacement string for underscore sign <code>_</code> during serializing/
|
||||
* deserializing information in eureka server.
|
||||
*/
|
||||
private String escapeCharReplacement = "__";
|
||||
|
||||
@@ -362,38 +374,45 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
/**
|
||||
* If set to true, local status updates via ApplicationInfoManager will trigger
|
||||
* on-demand (but rate limited) register/updates to remote eureka servers
|
||||
* on-demand (but rate limited) register/updates to remote eureka servers.
|
||||
*/
|
||||
private boolean onDemandUpdateStatusChange = true;
|
||||
|
||||
/**
|
||||
* This is a transient config and once the latest codecs are stable, can be removed
|
||||
* (as there will only be one)
|
||||
* (as there will only be one).
|
||||
*/
|
||||
private String encoderName;
|
||||
|
||||
/**
|
||||
* This is a transient config and once the latest codecs are stable, can be removed
|
||||
* (as there will only be one)
|
||||
* (as there will only be one).
|
||||
*/
|
||||
private String decoderName;
|
||||
|
||||
/**
|
||||
* EurekaAccept name for client data accept
|
||||
* EurekaAccept name for client data accept.
|
||||
*/
|
||||
private String clientDataAccept = EurekaAccept.full.name();
|
||||
|
||||
/**
|
||||
* Indicates whether the client should explicitly unregister itself from the remote server
|
||||
* on client shutdown.
|
||||
* Indicates whether the client should explicitly unregister itself from the remote
|
||||
* server on client shutdown.
|
||||
*/
|
||||
private boolean shouldUnregisterOnShutdown = true;
|
||||
|
||||
/**
|
||||
* Indicates whether the client should enforce registration during initialization. Defaults to false.
|
||||
* Indicates whether the client should enforce registration during initialization.
|
||||
* Defaults to false.
|
||||
*/
|
||||
private boolean shouldEnforceRegistrationAtInit = false;
|
||||
|
||||
/**
|
||||
* Order of the discovery client used by `CompositeDiscoveryClient` for sorting
|
||||
* available clients.
|
||||
*/
|
||||
private int order = 0;
|
||||
|
||||
@Override
|
||||
public boolean shouldGZipContent() {
|
||||
return this.gZipContent;
|
||||
@@ -496,8 +515,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
@Override
|
||||
public String getExperimental(String name) {
|
||||
if (this.propertyResolver != null) {
|
||||
return this.propertyResolver.getProperty(PREFIX + ".experimental." + name,
|
||||
String.class, null);
|
||||
return this.propertyResolver.getProperty(PREFIX + ".experimental." + name, String.class, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -545,8 +563,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return instanceInfoReplicationIntervalSeconds;
|
||||
}
|
||||
|
||||
public void setInstanceInfoReplicationIntervalSeconds(
|
||||
int instanceInfoReplicationIntervalSeconds) {
|
||||
public void setInstanceInfoReplicationIntervalSeconds(int instanceInfoReplicationIntervalSeconds) {
|
||||
this.instanceInfoReplicationIntervalSeconds = instanceInfoReplicationIntervalSeconds;
|
||||
}
|
||||
|
||||
@@ -555,8 +572,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return initialInstanceInfoReplicationIntervalSeconds;
|
||||
}
|
||||
|
||||
public void setInitialInstanceInfoReplicationIntervalSeconds(
|
||||
int initialInstanceInfoReplicationIntervalSeconds) {
|
||||
public void setInitialInstanceInfoReplicationIntervalSeconds(int initialInstanceInfoReplicationIntervalSeconds) {
|
||||
this.initialInstanceInfoReplicationIntervalSeconds = initialInstanceInfoReplicationIntervalSeconds;
|
||||
}
|
||||
|
||||
@@ -565,8 +581,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return eurekaServiceUrlPollIntervalSeconds;
|
||||
}
|
||||
|
||||
public void setEurekaServiceUrlPollIntervalSeconds(
|
||||
int eurekaServiceUrlPollIntervalSeconds) {
|
||||
public void setEurekaServiceUrlPollIntervalSeconds(int eurekaServiceUrlPollIntervalSeconds) {
|
||||
this.eurekaServiceUrlPollIntervalSeconds = eurekaServiceUrlPollIntervalSeconds;
|
||||
}
|
||||
|
||||
@@ -620,8 +635,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return eurekaServerConnectTimeoutSeconds;
|
||||
}
|
||||
|
||||
public void setEurekaServerConnectTimeoutSeconds(
|
||||
int eurekaServerConnectTimeoutSeconds) {
|
||||
public void setEurekaServerConnectTimeoutSeconds(int eurekaServerConnectTimeoutSeconds) {
|
||||
this.eurekaServerConnectTimeoutSeconds = eurekaServerConnectTimeoutSeconds;
|
||||
}
|
||||
|
||||
@@ -648,8 +662,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return eurekaServerTotalConnectionsPerHost;
|
||||
}
|
||||
|
||||
public void setEurekaServerTotalConnectionsPerHost(
|
||||
int eurekaServerTotalConnectionsPerHost) {
|
||||
public void setEurekaServerTotalConnectionsPerHost(int eurekaServerTotalConnectionsPerHost) {
|
||||
this.eurekaServerTotalConnectionsPerHost = eurekaServerTotalConnectionsPerHost;
|
||||
}
|
||||
|
||||
@@ -694,8 +707,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return eurekaConnectionIdleTimeoutSeconds;
|
||||
}
|
||||
|
||||
public void setEurekaConnectionIdleTimeoutSeconds(
|
||||
int eurekaConnectionIdleTimeoutSeconds) {
|
||||
public void setEurekaConnectionIdleTimeoutSeconds(int eurekaConnectionIdleTimeoutSeconds) {
|
||||
this.eurekaConnectionIdleTimeoutSeconds = eurekaConnectionIdleTimeoutSeconds;
|
||||
}
|
||||
|
||||
@@ -704,8 +716,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return registryRefreshSingleVipAddress;
|
||||
}
|
||||
|
||||
public void setRegistryRefreshSingleVipAddress(
|
||||
String registryRefreshSingleVipAddress) {
|
||||
public void setRegistryRefreshSingleVipAddress(String registryRefreshSingleVipAddress) {
|
||||
this.registryRefreshSingleVipAddress = registryRefreshSingleVipAddress;
|
||||
}
|
||||
|
||||
@@ -723,8 +734,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return heartbeatExecutorExponentialBackOffBound;
|
||||
}
|
||||
|
||||
public void setHeartbeatExecutorExponentialBackOffBound(
|
||||
int heartbeatExecutorExponentialBackOffBound) {
|
||||
public void setHeartbeatExecutorExponentialBackOffBound(int heartbeatExecutorExponentialBackOffBound) {
|
||||
this.heartbeatExecutorExponentialBackOffBound = heartbeatExecutorExponentialBackOffBound;
|
||||
}
|
||||
|
||||
@@ -733,8 +743,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return cacheRefreshExecutorThreadPoolSize;
|
||||
}
|
||||
|
||||
public void setCacheRefreshExecutorThreadPoolSize(
|
||||
int cacheRefreshExecutorThreadPoolSize) {
|
||||
public void setCacheRefreshExecutorThreadPoolSize(int cacheRefreshExecutorThreadPoolSize) {
|
||||
this.cacheRefreshExecutorThreadPoolSize = cacheRefreshExecutorThreadPoolSize;
|
||||
}
|
||||
|
||||
@@ -743,8 +752,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
return cacheRefreshExecutorExponentialBackOffBound;
|
||||
}
|
||||
|
||||
public void setCacheRefreshExecutorExponentialBackOffBound(
|
||||
int cacheRefreshExecutorExponentialBackOffBound) {
|
||||
public void setCacheRefreshExecutorExponentialBackOffBound(int cacheRefreshExecutorExponentialBackOffBound) {
|
||||
this.cacheRefreshExecutorExponentialBackOffBound = cacheRefreshExecutorExponentialBackOffBound;
|
||||
}
|
||||
|
||||
@@ -913,131 +921,124 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
this.shouldEnforceRegistrationAtInit = shouldEnforceRegistrationAtInit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
EurekaClientConfigBean that = (EurekaClientConfigBean) o;
|
||||
return Objects.equals(propertyResolver, that.propertyResolver) &&
|
||||
enabled == that.enabled &&
|
||||
Objects.equals(transport, that.transport) &&
|
||||
registryFetchIntervalSeconds == that.registryFetchIntervalSeconds &&
|
||||
instanceInfoReplicationIntervalSeconds == that.instanceInfoReplicationIntervalSeconds &&
|
||||
initialInstanceInfoReplicationIntervalSeconds == that.initialInstanceInfoReplicationIntervalSeconds &&
|
||||
eurekaServiceUrlPollIntervalSeconds == that.eurekaServiceUrlPollIntervalSeconds &&
|
||||
eurekaServerReadTimeoutSeconds == that.eurekaServerReadTimeoutSeconds &&
|
||||
eurekaServerConnectTimeoutSeconds == that.eurekaServerConnectTimeoutSeconds &&
|
||||
eurekaServerTotalConnections == that.eurekaServerTotalConnections &&
|
||||
eurekaServerTotalConnectionsPerHost == that.eurekaServerTotalConnectionsPerHost &&
|
||||
eurekaConnectionIdleTimeoutSeconds == that.eurekaConnectionIdleTimeoutSeconds &&
|
||||
heartbeatExecutorThreadPoolSize == that.heartbeatExecutorThreadPoolSize &&
|
||||
heartbeatExecutorExponentialBackOffBound == that.heartbeatExecutorExponentialBackOffBound &&
|
||||
cacheRefreshExecutorThreadPoolSize == that.cacheRefreshExecutorThreadPoolSize &&
|
||||
cacheRefreshExecutorExponentialBackOffBound == that.cacheRefreshExecutorExponentialBackOffBound &&
|
||||
gZipContent == that.gZipContent &&
|
||||
useDnsForFetchingServiceUrls == that.useDnsForFetchingServiceUrls &&
|
||||
registerWithEureka == that.registerWithEureka &&
|
||||
preferSameZoneEureka == that.preferSameZoneEureka &&
|
||||
logDeltaDiff == that.logDeltaDiff &&
|
||||
disableDelta == that.disableDelta &&
|
||||
filterOnlyUpInstances == that.filterOnlyUpInstances &&
|
||||
fetchRegistry == that.fetchRegistry &&
|
||||
allowRedirects == that.allowRedirects &&
|
||||
onDemandUpdateStatusChange == that.onDemandUpdateStatusChange &&
|
||||
shouldUnregisterOnShutdown == that.shouldUnregisterOnShutdown &&
|
||||
shouldEnforceRegistrationAtInit == that.shouldEnforceRegistrationAtInit &&
|
||||
Objects.equals(proxyPort, that.proxyPort) &&
|
||||
Objects.equals(proxyHost, that.proxyHost) &&
|
||||
Objects.equals(proxyUserName, that.proxyUserName) &&
|
||||
Objects.equals(proxyPassword, that.proxyPassword) &&
|
||||
Objects.equals(backupRegistryImpl, that.backupRegistryImpl) &&
|
||||
Objects.equals(eurekaServerURLContext, that.eurekaServerURLContext) &&
|
||||
Objects.equals(eurekaServerPort, that.eurekaServerPort) &&
|
||||
Objects.equals(eurekaServerDNSName, that.eurekaServerDNSName) &&
|
||||
Objects.equals(region, that.region) &&
|
||||
Objects.equals(registryRefreshSingleVipAddress, that.registryRefreshSingleVipAddress) &&
|
||||
Objects.equals(serviceUrl, that.serviceUrl) &&
|
||||
Objects.equals(fetchRemoteRegionsRegistry, that.fetchRemoteRegionsRegistry) &&
|
||||
Objects.equals(availabilityZones, that.availabilityZones) &&
|
||||
Objects.equals(dollarReplacement, that.dollarReplacement) &&
|
||||
Objects.equals(escapeCharReplacement, that.escapeCharReplacement) &&
|
||||
Objects.equals(encoderName, that.encoderName) &&
|
||||
Objects.equals(decoderName, that.decoderName) &&
|
||||
Objects.equals(clientDataAccept, that.clientDataAccept);
|
||||
return Objects.equals(propertyResolver, that.propertyResolver) && enabled == that.enabled
|
||||
&& Objects.equals(transport, that.transport)
|
||||
&& registryFetchIntervalSeconds == that.registryFetchIntervalSeconds
|
||||
&& instanceInfoReplicationIntervalSeconds == that.instanceInfoReplicationIntervalSeconds
|
||||
&& initialInstanceInfoReplicationIntervalSeconds == that.initialInstanceInfoReplicationIntervalSeconds
|
||||
&& eurekaServiceUrlPollIntervalSeconds == that.eurekaServiceUrlPollIntervalSeconds
|
||||
&& eurekaServerReadTimeoutSeconds == that.eurekaServerReadTimeoutSeconds
|
||||
&& eurekaServerConnectTimeoutSeconds == that.eurekaServerConnectTimeoutSeconds
|
||||
&& eurekaServerTotalConnections == that.eurekaServerTotalConnections
|
||||
&& eurekaServerTotalConnectionsPerHost == that.eurekaServerTotalConnectionsPerHost
|
||||
&& eurekaConnectionIdleTimeoutSeconds == that.eurekaConnectionIdleTimeoutSeconds
|
||||
&& heartbeatExecutorThreadPoolSize == that.heartbeatExecutorThreadPoolSize
|
||||
&& heartbeatExecutorExponentialBackOffBound == that.heartbeatExecutorExponentialBackOffBound
|
||||
&& cacheRefreshExecutorThreadPoolSize == that.cacheRefreshExecutorThreadPoolSize
|
||||
&& cacheRefreshExecutorExponentialBackOffBound == that.cacheRefreshExecutorExponentialBackOffBound
|
||||
&& gZipContent == that.gZipContent && useDnsForFetchingServiceUrls == that.useDnsForFetchingServiceUrls
|
||||
&& registerWithEureka == that.registerWithEureka && preferSameZoneEureka == that.preferSameZoneEureka
|
||||
&& logDeltaDiff == that.logDeltaDiff && disableDelta == that.disableDelta
|
||||
&& filterOnlyUpInstances == that.filterOnlyUpInstances && fetchRegistry == that.fetchRegistry
|
||||
&& allowRedirects == that.allowRedirects
|
||||
&& onDemandUpdateStatusChange == that.onDemandUpdateStatusChange
|
||||
&& shouldUnregisterOnShutdown == that.shouldUnregisterOnShutdown
|
||||
&& shouldEnforceRegistrationAtInit == that.shouldEnforceRegistrationAtInit
|
||||
&& Objects.equals(proxyPort, that.proxyPort) && Objects.equals(proxyHost, that.proxyHost)
|
||||
&& Objects.equals(proxyUserName, that.proxyUserName)
|
||||
&& Objects.equals(proxyPassword, that.proxyPassword)
|
||||
&& Objects.equals(backupRegistryImpl, that.backupRegistryImpl)
|
||||
&& Objects.equals(eurekaServerURLContext, that.eurekaServerURLContext)
|
||||
&& Objects.equals(eurekaServerPort, that.eurekaServerPort)
|
||||
&& Objects.equals(eurekaServerDNSName, that.eurekaServerDNSName) && Objects.equals(region, that.region)
|
||||
&& Objects.equals(registryRefreshSingleVipAddress, that.registryRefreshSingleVipAddress)
|
||||
&& Objects.equals(serviceUrl, that.serviceUrl)
|
||||
&& Objects.equals(fetchRemoteRegionsRegistry, that.fetchRemoteRegionsRegistry)
|
||||
&& Objects.equals(availabilityZones, that.availabilityZones)
|
||||
&& Objects.equals(dollarReplacement, that.dollarReplacement)
|
||||
&& Objects.equals(escapeCharReplacement, that.escapeCharReplacement)
|
||||
&& Objects.equals(encoderName, that.encoderName) && Objects.equals(decoderName, that.decoderName)
|
||||
&& Objects.equals(clientDataAccept, that.clientDataAccept) && Objects.equals(order, that.order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(propertyResolver, enabled, transport,
|
||||
registryFetchIntervalSeconds, instanceInfoReplicationIntervalSeconds,
|
||||
initialInstanceInfoReplicationIntervalSeconds,
|
||||
eurekaServiceUrlPollIntervalSeconds, proxyPort, proxyHost, proxyUserName,
|
||||
proxyPassword, eurekaServerReadTimeoutSeconds,
|
||||
eurekaServerConnectTimeoutSeconds, backupRegistryImpl,
|
||||
eurekaServerTotalConnections, eurekaServerTotalConnectionsPerHost,
|
||||
eurekaServerURLContext, eurekaServerPort, eurekaServerDNSName, region,
|
||||
eurekaConnectionIdleTimeoutSeconds, registryRefreshSingleVipAddress,
|
||||
heartbeatExecutorThreadPoolSize, heartbeatExecutorExponentialBackOffBound,
|
||||
cacheRefreshExecutorThreadPoolSize,
|
||||
cacheRefreshExecutorExponentialBackOffBound, serviceUrl, gZipContent,
|
||||
useDnsForFetchingServiceUrls, registerWithEureka, preferSameZoneEureka,
|
||||
logDeltaDiff, disableDelta, fetchRemoteRegionsRegistry, availabilityZones,
|
||||
filterOnlyUpInstances, fetchRegistry, dollarReplacement,
|
||||
escapeCharReplacement, allowRedirects, onDemandUpdateStatusChange,
|
||||
encoderName, decoderName, clientDataAccept, shouldUnregisterOnShutdown,
|
||||
shouldEnforceRegistrationAtInit);
|
||||
return Objects.hash(propertyResolver, enabled, transport, registryFetchIntervalSeconds,
|
||||
instanceInfoReplicationIntervalSeconds, initialInstanceInfoReplicationIntervalSeconds,
|
||||
eurekaServiceUrlPollIntervalSeconds, proxyPort, proxyHost, proxyUserName, proxyPassword,
|
||||
eurekaServerReadTimeoutSeconds, eurekaServerConnectTimeoutSeconds, backupRegistryImpl,
|
||||
eurekaServerTotalConnections, eurekaServerTotalConnectionsPerHost, eurekaServerURLContext,
|
||||
eurekaServerPort, eurekaServerDNSName, region, eurekaConnectionIdleTimeoutSeconds,
|
||||
registryRefreshSingleVipAddress, heartbeatExecutorThreadPoolSize,
|
||||
heartbeatExecutorExponentialBackOffBound, cacheRefreshExecutorThreadPoolSize,
|
||||
cacheRefreshExecutorExponentialBackOffBound, serviceUrl, gZipContent, useDnsForFetchingServiceUrls,
|
||||
registerWithEureka, preferSameZoneEureka, logDeltaDiff, disableDelta, fetchRemoteRegionsRegistry,
|
||||
availabilityZones, filterOnlyUpInstances, fetchRegistry, dollarReplacement, escapeCharReplacement,
|
||||
allowRedirects, onDemandUpdateStatusChange, encoderName, decoderName, clientDataAccept,
|
||||
shouldUnregisterOnShutdown, shouldEnforceRegistrationAtInit, order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("EurekaClientConfigBean{")
|
||||
.append("propertyResolver=").append(propertyResolver).append(", ")
|
||||
.append("enabled=").append(enabled).append(", ")
|
||||
.append("transport=").append(transport).append(", ")
|
||||
.append("registryFetchIntervalSeconds=").append(registryFetchIntervalSeconds).append(", ")
|
||||
.append("instanceInfoReplicationIntervalSeconds=").append(instanceInfoReplicationIntervalSeconds).append(", ")
|
||||
.append("initialInstanceInfoReplicationIntervalSeconds=").append(initialInstanceInfoReplicationIntervalSeconds).append(", ")
|
||||
return new StringBuilder("EurekaClientConfigBean{").append("propertyResolver=").append(propertyResolver)
|
||||
.append(", ").append("enabled=").append(enabled).append(", ").append("transport=").append(transport)
|
||||
.append(", ").append("registryFetchIntervalSeconds=").append(registryFetchIntervalSeconds).append(", ")
|
||||
.append("instanceInfoReplicationIntervalSeconds=").append(instanceInfoReplicationIntervalSeconds)
|
||||
.append(", ").append("initialInstanceInfoReplicationIntervalSeconds=")
|
||||
.append(initialInstanceInfoReplicationIntervalSeconds).append(", ")
|
||||
.append("eurekaServiceUrlPollIntervalSeconds=").append(eurekaServiceUrlPollIntervalSeconds).append(", ")
|
||||
.append("proxyPort='").append(proxyPort).append("', ")
|
||||
.append("proxyHost='").append(proxyHost).append("', ")
|
||||
.append("proxyUserName='").append(proxyUserName).append("', ")
|
||||
.append("proxyPassword='").append(proxyPassword).append("', ")
|
||||
.append("eurekaServerReadTimeoutSeconds=").append(eurekaServerReadTimeoutSeconds).append(", ")
|
||||
.append("eurekaServerConnectTimeoutSeconds=").append(eurekaServerConnectTimeoutSeconds).append(", ")
|
||||
.append("backupRegistryImpl='").append(backupRegistryImpl).append("', ")
|
||||
.append("eurekaServerTotalConnections=").append(eurekaServerTotalConnections).append(", ")
|
||||
.append("eurekaServerTotalConnectionsPerHost=").append(eurekaServerTotalConnectionsPerHost).append(", ")
|
||||
.append("eurekaServerURLContext='").append(eurekaServerURLContext).append("', ")
|
||||
.append("eurekaServerPort='").append(eurekaServerPort).append("', ")
|
||||
.append("eurekaServerDNSName='").append(eurekaServerDNSName).append("', ")
|
||||
.append("region='").append(region).append("', ")
|
||||
.append("eurekaConnectionIdleTimeoutSeconds=").append(eurekaConnectionIdleTimeoutSeconds).append(", ")
|
||||
.append("registryRefreshSingleVipAddress='").append(registryRefreshSingleVipAddress).append("', ")
|
||||
.append("heartbeatExecutorThreadPoolSize=").append(heartbeatExecutorThreadPoolSize).append(", ")
|
||||
.append("heartbeatExecutorExponentialBackOffBound=").append(heartbeatExecutorExponentialBackOffBound).append(", ")
|
||||
.append("cacheRefreshExecutorThreadPoolSize=").append(cacheRefreshExecutorThreadPoolSize).append(", ")
|
||||
.append("cacheRefreshExecutorExponentialBackOffBound=").append(cacheRefreshExecutorExponentialBackOffBound).append(", ")
|
||||
.append("serviceUrl=").append(serviceUrl).append(", ")
|
||||
.append("gZipContent=").append(gZipContent).append(", ")
|
||||
.append("proxyPort='").append(proxyPort).append("', ").append("proxyHost='").append(proxyHost)
|
||||
.append("', ").append("proxyUserName='").append(proxyUserName).append("', ").append("proxyPassword='")
|
||||
.append(proxyPassword).append("', ").append("eurekaServerReadTimeoutSeconds=")
|
||||
.append(eurekaServerReadTimeoutSeconds).append(", ").append("eurekaServerConnectTimeoutSeconds=")
|
||||
.append(eurekaServerConnectTimeoutSeconds).append(", ").append("backupRegistryImpl='")
|
||||
.append(backupRegistryImpl).append("', ").append("eurekaServerTotalConnections=")
|
||||
.append(eurekaServerTotalConnections).append(", ").append("eurekaServerTotalConnectionsPerHost=")
|
||||
.append(eurekaServerTotalConnectionsPerHost).append(", ").append("eurekaServerURLContext='")
|
||||
.append(eurekaServerURLContext).append("', ").append("eurekaServerPort='").append(eurekaServerPort)
|
||||
.append("', ").append("eurekaServerDNSName='").append(eurekaServerDNSName).append("', ")
|
||||
.append("region='").append(region).append("', ").append("eurekaConnectionIdleTimeoutSeconds=")
|
||||
.append(eurekaConnectionIdleTimeoutSeconds).append(", ").append("registryRefreshSingleVipAddress='")
|
||||
.append(registryRefreshSingleVipAddress).append("', ").append("heartbeatExecutorThreadPoolSize=")
|
||||
.append(heartbeatExecutorThreadPoolSize).append(", ")
|
||||
.append("heartbeatExecutorExponentialBackOffBound=").append(heartbeatExecutorExponentialBackOffBound)
|
||||
.append(", ").append("cacheRefreshExecutorThreadPoolSize=").append(cacheRefreshExecutorThreadPoolSize)
|
||||
.append(", ").append("cacheRefreshExecutorExponentialBackOffBound=")
|
||||
.append(cacheRefreshExecutorExponentialBackOffBound).append(", ").append("serviceUrl=")
|
||||
.append(serviceUrl).append(", ").append("gZipContent=").append(gZipContent).append(", ")
|
||||
.append("useDnsForFetchingServiceUrls=").append(useDnsForFetchingServiceUrls).append(", ")
|
||||
.append("registerWithEureka=").append(registerWithEureka).append(", ")
|
||||
.append("preferSameZoneEureka=").append(preferSameZoneEureka).append(", ")
|
||||
.append("logDeltaDiff=").append(logDeltaDiff).append(", ")
|
||||
.append("disableDelta=").append(disableDelta).append(", ")
|
||||
.append("fetchRemoteRegionsRegistry='").append(fetchRemoteRegionsRegistry).append("', ")
|
||||
.append("availabilityZones=").append(availabilityZones).append(", ")
|
||||
.append("filterOnlyUpInstances=").append(filterOnlyUpInstances).append(", ")
|
||||
.append("fetchRegistry=").append(fetchRegistry).append(", ")
|
||||
.append("dollarReplacement='").append(dollarReplacement).append("', ")
|
||||
.append("escapeCharReplacement='").append(escapeCharReplacement).append("', ")
|
||||
.append("allowRedirects=").append(allowRedirects).append(", ")
|
||||
.append("registerWithEureka=").append(registerWithEureka).append(", ").append("preferSameZoneEureka=")
|
||||
.append(preferSameZoneEureka).append(", ").append("logDeltaDiff=").append(logDeltaDiff).append(", ")
|
||||
.append("disableDelta=").append(disableDelta).append(", ").append("fetchRemoteRegionsRegistry='")
|
||||
.append(fetchRemoteRegionsRegistry).append("', ").append("availabilityZones=").append(availabilityZones)
|
||||
.append(", ").append("filterOnlyUpInstances=").append(filterOnlyUpInstances).append(", ")
|
||||
.append("fetchRegistry=").append(fetchRegistry).append(", ").append("dollarReplacement='")
|
||||
.append(dollarReplacement).append("', ").append("escapeCharReplacement='").append(escapeCharReplacement)
|
||||
.append("', ").append("allowRedirects=").append(allowRedirects).append(", ")
|
||||
.append("onDemandUpdateStatusChange=").append(onDemandUpdateStatusChange).append(", ")
|
||||
.append("encoderName='").append(encoderName).append("', ")
|
||||
.append("decoderName='").append(decoderName).append("', ")
|
||||
.append("clientDataAccept='").append(clientDataAccept).append("'").append("}")
|
||||
.append("=shouldUnregisterOnShutdown'").append(shouldUnregisterOnShutdown).append("'").append("}")
|
||||
.append("shouldEnforceRegistrationAtInit='").append(shouldEnforceRegistrationAtInit).append("'").append("}")
|
||||
.toString();
|
||||
.append("encoderName='").append(encoderName).append("', ").append("decoderName='").append(decoderName)
|
||||
.append("', ").append("clientDataAccept='").append(clientDataAccept).append("', ")
|
||||
.append("shouldUnregisterOnShutdown='").append(shouldUnregisterOnShutdown)
|
||||
.append("shouldEnforceRegistrationAtInit='").append(shouldEnforceRegistrationAtInit).append("', ")
|
||||
.append("order='").append(order).append("'}").toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,10 +17,15 @@
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
/**
|
||||
* Class containing Eureka-specific constants.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class EurekaConstants {
|
||||
public final class EurekaConstants {
|
||||
|
||||
/**
|
||||
* Default Eureka prefix.
|
||||
*/
|
||||
public static final String DEFAULT_PREFIX = "/eureka";
|
||||
|
||||
private EurekaConstants() {
|
||||
|
||||
+21
-63
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,38 +16,39 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.client.DefaultServiceInstance;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.EurekaClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
|
||||
import static com.netflix.appinfo.InstanceInfo.PortType.SECURE;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* A {@link DiscoveryClient} implementation for Eureka.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Tim Ysewyn
|
||||
*/
|
||||
public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
/**
|
||||
* Client description {@link String}.
|
||||
*/
|
||||
public static final String DESCRIPTION = "Spring Cloud Eureka Discovery Client";
|
||||
|
||||
private final EurekaInstanceConfig config;
|
||||
|
||||
private final EurekaClient eurekaClient;
|
||||
|
||||
public EurekaDiscoveryClient(EurekaInstanceConfig config, EurekaClient eurekaClient) {
|
||||
this.config = config;
|
||||
private final EurekaClientConfig clientConfig;
|
||||
|
||||
public EurekaDiscoveryClient(EurekaClient eurekaClient, EurekaClientConfig clientConfig) {
|
||||
this.clientConfig = clientConfig;
|
||||
this.eurekaClient = eurekaClient;
|
||||
}
|
||||
|
||||
@@ -58,8 +59,7 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String serviceId) {
|
||||
List<InstanceInfo> infos = this.eurekaClient.getInstancesByVipAddress(serviceId,
|
||||
false);
|
||||
List<InstanceInfo> infos = this.eurekaClient.getInstancesByVipAddress(serviceId, false);
|
||||
List<ServiceInstance> instances = new ArrayList<>();
|
||||
for (InstanceInfo info : infos) {
|
||||
instances.add(new EurekaServiceInstance(info));
|
||||
@@ -67,53 +67,6 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
return instances;
|
||||
}
|
||||
|
||||
public static class EurekaServiceInstance implements ServiceInstance {
|
||||
private InstanceInfo instance;
|
||||
|
||||
public EurekaServiceInstance(InstanceInfo instance) {
|
||||
Assert.notNull(instance, "Service instance required");
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public InstanceInfo getInstanceInfo() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return this.instance.getAppName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return this.instance.getHostName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
if (isSecure()) {
|
||||
return this.instance.getSecurePort();
|
||||
}
|
||||
return this.instance.getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
// assume if secure is enabled, that is the default
|
||||
return this.instance.isPortEnabled(SECURE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUri() {
|
||||
return DefaultServiceInstance.getUri(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMetadata() {
|
||||
return this.instance.getMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getServices() {
|
||||
Applications applications = this.eurekaClient.getApplications();
|
||||
@@ -132,4 +85,9 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
return names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return clientConfig instanceof Ordered ? ((Ordered) clientConfig).getOrder() : DiscoveryClient.DEFAULT_ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+32
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,18 +21,19 @@ import com.netflix.discovery.EurekaClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.health.HealthAggregator;
|
||||
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
|
||||
import org.springframework.boot.actuate.health.SimpleStatusAggregator;
|
||||
import org.springframework.boot.actuate.health.StatusAggregator;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
|
||||
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -40,22 +41,41 @@ import org.springframework.context.event.EventListener;
|
||||
* @author Jon Schneider
|
||||
* @author Jakub Narloch
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author Tim Ysewyn
|
||||
*/
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass(EurekaClientConfig.class)
|
||||
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
|
||||
@ConditionalOnDiscoveryEnabled
|
||||
@ConditionalOnBlockingDiscoveryEnabled
|
||||
public class EurekaDiscoveryClientConfiguration {
|
||||
|
||||
@Bean
|
||||
public Marker eurekaDiscoverClientMarker() {
|
||||
return new Marker();
|
||||
@ConditionalOnMissingBean
|
||||
public EurekaDiscoveryClient discoveryClient(EurekaClient client, EurekaClientConfig clientConfig) {
|
||||
return new EurekaDiscoveryClient(client, clientConfig);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false)
|
||||
protected static class EurekaHealthCheckHandlerConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private StatusAggregator statusAggregator = new SimpleStatusAggregator();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(HealthCheckHandler.class)
|
||||
public EurekaHealthCheckHandler eurekaHealthCheckHandler() {
|
||||
return new EurekaHealthCheckHandler(this.statusAggregator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(RefreshScopeRefreshedEvent.class)
|
||||
protected static class EurekaClientConfigurationRefresher {
|
||||
protected static class EurekaClientConfigurationRefresher
|
||||
implements ApplicationListener<RefreshScopeRefreshedEvent> {
|
||||
|
||||
@Autowired(required = false)
|
||||
private EurekaClient eurekaClient;
|
||||
@@ -63,10 +83,9 @@ public class EurekaDiscoveryClientConfiguration {
|
||||
@Autowired(required = false)
|
||||
private EurekaAutoServiceRegistration autoRegistration;
|
||||
|
||||
@EventListener(RefreshScopeRefreshedEvent.class)
|
||||
public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
|
||||
//This will force the creation of the EurkaClient bean if not already created
|
||||
//to make sure the client will be reregistered after a refresh event
|
||||
// This will force the creation of the EurkaClient bean if not already created
|
||||
// to make sure the client will be reregistered after a refresh event
|
||||
if (eurekaClient != null) {
|
||||
eurekaClient.getApplications();
|
||||
}
|
||||
@@ -76,21 +95,7 @@ public class EurekaDiscoveryClientConfiguration {
|
||||
this.autoRegistration.start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false)
|
||||
protected static class EurekaHealthCheckHandlerConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private HealthAggregator healthAggregator = new OrderedHealthAggregator();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(HealthCheckHandler.class)
|
||||
public EurekaHealthCheckHandler eurekaHealthCheckHandler() {
|
||||
return new EurekaHealthCheckHandler(this.healthAggregator);
|
||||
}
|
||||
}
|
||||
|
||||
class Marker { }
|
||||
}
|
||||
|
||||
+138
-42
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,53 +17,82 @@
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.netflix.appinfo.HealthCheckHandler;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.actuate.health.CompositeHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.HealthAggregator;
|
||||
import org.springframework.boot.actuate.health.CompositeHealthContributor;
|
||||
import org.springframework.boot.actuate.health.CompositeReactiveHealthContributor;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.HealthContributor;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.NamedContributor;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthContributor;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.StatusAggregator;
|
||||
import org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthContributor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
|
||||
/**
|
||||
* A Eureka health checker, maps the application status into {@link InstanceStatus}
|
||||
* that will be propagated to Eureka registry.
|
||||
* A Eureka health checker, maps the application status into {@link InstanceStatus} that
|
||||
* will be propagated to Eureka registry.
|
||||
*
|
||||
* On each heartbeat Eureka performs the health check invoking registered {@link HealthCheckHandler}. By default this
|
||||
* implementation will perform aggregation of all registered {@link HealthIndicator}
|
||||
* through registered {@link HealthAggregator}.
|
||||
* On each heartbeat Eureka performs the health check invoking registered
|
||||
* {@link HealthCheckHandler}. By default this implementation will perform aggregation of
|
||||
* all registered {@link HealthIndicator} through registered {@link StatusAggregator}.
|
||||
*
|
||||
* A {@code null} status is returned when the application context is closed (or in the
|
||||
* process of being closed). This prevents Eureka from updating the health status and only
|
||||
* consider the status present in the current InstanceInfo.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
* @author Spencer Gibb
|
||||
* @author Nowrin Anwar Joyita
|
||||
* @author Bertrand Renuart
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @see HealthCheckHandler
|
||||
* @see HealthAggregator
|
||||
* @see StatusAggregator
|
||||
*/
|
||||
public class EurekaHealthCheckHandler implements HealthCheckHandler, ApplicationContextAware, InitializingBean {
|
||||
public class EurekaHealthCheckHandler
|
||||
implements HealthCheckHandler, ApplicationContextAware, InitializingBean, Ordered, Lifecycle {
|
||||
|
||||
private static final Map<Status, InstanceInfo.InstanceStatus> STATUS_MAPPING =
|
||||
new HashMap<Status, InstanceInfo.InstanceStatus>() {{
|
||||
put(Status.UNKNOWN, InstanceStatus.UNKNOWN);
|
||||
put(Status.OUT_OF_SERVICE, InstanceStatus.OUT_OF_SERVICE);
|
||||
put(Status.DOWN, InstanceStatus.DOWN);
|
||||
put(Status.UP, InstanceStatus.UP);
|
||||
}};
|
||||
private static final Map<Status, InstanceInfo.InstanceStatus> STATUS_MAPPING = new HashMap<Status, InstanceInfo.InstanceStatus>() {
|
||||
{
|
||||
put(Status.UNKNOWN, InstanceStatus.UNKNOWN);
|
||||
put(Status.OUT_OF_SERVICE, InstanceStatus.DOWN);
|
||||
put(Status.DOWN, InstanceStatus.DOWN);
|
||||
put(Status.UP, InstanceStatus.UP);
|
||||
}
|
||||
};
|
||||
|
||||
private final CompositeHealthIndicator healthIndicator;
|
||||
private StatusAggregator statusAggregator;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public EurekaHealthCheckHandler(HealthAggregator healthAggregator) {
|
||||
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
|
||||
this.healthIndicator = new CompositeHealthIndicator(healthAggregator);
|
||||
private Map<String, HealthContributor> healthContributors = new HashMap<>();
|
||||
|
||||
/**
|
||||
* {@code true} until the context is stopped.
|
||||
*/
|
||||
private boolean running = true;
|
||||
|
||||
private Map<String, ReactiveHealthContributor> reactiveHealthContributors = new HashMap<>();
|
||||
|
||||
public EurekaHealthCheckHandler(StatusAggregator statusAggregator) {
|
||||
this.statusAggregator = statusAggregator;
|
||||
Assert.notNull(statusAggregator, "StatusAggregator must not be null");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,38 +101,83 @@ public class EurekaHealthCheckHandler implements HealthCheckHandler, Application
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
final Map<String, HealthIndicator> healthIndicators = applicationContext.getBeansOfType(HealthIndicator.class);
|
||||
public void afterPropertiesSet() {
|
||||
populateHealthContributors(applicationContext.getBeansOfType(HealthContributor.class));
|
||||
reactiveHealthContributors.putAll(applicationContext.getBeansOfType(ReactiveHealthContributor.class));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
|
||||
|
||||
//ignore EurekaHealthIndicator and flatten the rest of the composite
|
||||
//otherwise there is a never ending cycle of down. See gh-643
|
||||
if (entry.getValue() instanceof DiscoveryCompositeHealthIndicator) {
|
||||
DiscoveryCompositeHealthIndicator indicator = (DiscoveryCompositeHealthIndicator) entry.getValue();
|
||||
for (DiscoveryCompositeHealthIndicator.Holder holder : indicator.getHealthIndicators()) {
|
||||
if (!(holder.getDelegate() instanceof EurekaHealthIndicator)) {
|
||||
healthIndicator.addHealthIndicator(holder.getDelegate().getName(), holder);
|
||||
void populateHealthContributors(Map<String, HealthContributor> healthContributors) {
|
||||
for (Map.Entry<String, HealthContributor> entry : healthContributors.entrySet()) {
|
||||
// ignore EurekaHealthIndicator and flatten the rest of the composite
|
||||
// otherwise there is a never ending cycle of down. See gh-643
|
||||
if (entry.getValue() instanceof DiscoveryCompositeHealthContributor) {
|
||||
DiscoveryCompositeHealthContributor indicator = (DiscoveryCompositeHealthContributor) entry.getValue();
|
||||
indicator.getIndicators().forEach((name, discoveryHealthIndicator) -> {
|
||||
if (!(discoveryHealthIndicator instanceof EurekaHealthIndicator)) {
|
||||
this.healthContributors.put(name, (HealthIndicator) discoveryHealthIndicator::health);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
else {
|
||||
healthIndicator.addHealthIndicator(entry.getKey(), entry.getValue());
|
||||
this.healthContributors.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceStatus getStatus(InstanceStatus instanceStatus) {
|
||||
return getHealthStatus();
|
||||
if (running) {
|
||||
return getHealthStatus();
|
||||
}
|
||||
else {
|
||||
// Return nothing if the context is not running, so the status held by the
|
||||
// InstanceInfo remains unchanged.
|
||||
// See gh-1571
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected InstanceStatus getHealthStatus() {
|
||||
final Status status = getHealthIndicator().health().getStatus();
|
||||
Status status = getStatus(statusAggregator);
|
||||
return mapToInstanceStatus(status);
|
||||
}
|
||||
|
||||
protected Status getStatus(StatusAggregator statusAggregator) {
|
||||
Set<Status> statusSet = new HashSet<>();
|
||||
for (HealthContributor contributor : healthContributors.values()) {
|
||||
processContributor(statusSet, contributor);
|
||||
}
|
||||
for (ReactiveHealthContributor contributor : reactiveHealthContributors.values()) {
|
||||
processContributor(statusSet, contributor);
|
||||
}
|
||||
return statusAggregator.getAggregateStatus(statusSet);
|
||||
}
|
||||
|
||||
private void processContributor(Set<Status> statusSet, HealthContributor contributor) {
|
||||
if (contributor instanceof CompositeHealthContributor) {
|
||||
for (NamedContributor<HealthContributor> contrib : (CompositeHealthContributor) contributor) {
|
||||
processContributor(statusSet, contrib.getContributor());
|
||||
}
|
||||
}
|
||||
else if (contributor instanceof HealthIndicator) {
|
||||
statusSet.add(((HealthIndicator) contributor).health().getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
private void processContributor(Set<Status> statusSet, ReactiveHealthContributor contributor) {
|
||||
if (contributor instanceof CompositeReactiveHealthContributor) {
|
||||
for (NamedContributor<ReactiveHealthContributor> contrib : (CompositeReactiveHealthContributor) contributor) {
|
||||
processContributor(statusSet, contrib.getContributor());
|
||||
}
|
||||
}
|
||||
else if (contributor instanceof ReactiveHealthIndicator) {
|
||||
Health health = ((ReactiveHealthIndicator) contributor).health().block();
|
||||
if (health != null) {
|
||||
statusSet.add(health.getStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected InstanceStatus mapToInstanceStatus(Status status) {
|
||||
if (!STATUS_MAPPING.containsKey(status)) {
|
||||
return InstanceStatus.UNKNOWN;
|
||||
@@ -111,7 +185,29 @@ public class EurekaHealthCheckHandler implements HealthCheckHandler, Application
|
||||
return STATUS_MAPPING.get(status);
|
||||
}
|
||||
|
||||
protected CompositeHealthIndicator getHealthIndicator() {
|
||||
return healthIndicator;
|
||||
@Override
|
||||
public int getOrder() {
|
||||
// registered with a high order priority so the close() method is invoked early
|
||||
// and *BEFORE* EurekaAutoServiceRegistration
|
||||
// (must be in effect when the registration is closed and the eureka replication
|
||||
// triggered -> health check handler is
|
||||
// consulted at that moment)
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
running = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user