mirror of
https://github.com/spring-cloud/spring-cloud-netflix.git
synced 2026-09-20 00:59:01 +00:00
Compare commits
1539
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b654016e73 | ||
|
|
f55c95b5f3 | ||
|
|
80af1ddcf5 | ||
|
|
921d1dbae5 | ||
|
|
8a01660f6b | ||
|
|
ebfc626538 | ||
|
|
567ebda132 | ||
|
|
f524c3bb2a | ||
|
|
67f472771e | ||
|
|
66a67bb353 | ||
|
|
55884acd85 | ||
|
|
153bf0ea63 | ||
|
|
4ab9897b3b | ||
|
|
2fffb2606e | ||
|
|
89ed8219cb | ||
|
|
a1f7bab91a | ||
|
|
60bb89293c | ||
|
|
151fad898b | ||
|
|
aa757592b6 | ||
|
|
90290757cb | ||
|
|
dfdc6c39e9 | ||
|
|
00587bae01 | ||
|
|
504ff8e7d4 | ||
|
|
1510258e2b | ||
|
|
59a4e430a0 | ||
|
|
70008f7717 | ||
|
|
1897c958d1 | ||
|
|
0c3fbc34f6 | ||
|
|
01ac98df8f | ||
|
|
3a62567ec8 | ||
|
|
3f0a43f913 | ||
|
|
53e7464a6e | ||
|
|
9eb5e64cd0 | ||
|
|
edd24bc51b | ||
|
|
8bfc0d514c | ||
|
|
e814cdabb6 | ||
|
|
8125edd772 | ||
|
|
a0041e1d63 | ||
|
|
f53ff6d45f | ||
|
|
482deb0485 | ||
|
|
81579f522f | ||
|
|
cd70fb5023 | ||
|
|
6e8ef02a14 | ||
|
|
dd19bc5ba3 | ||
|
|
46719c0c31 | ||
|
|
d98b3ce3d6 | ||
|
|
f19c7fbbe2 | ||
|
|
4aec32fde0 | ||
|
|
5c062ef01a | ||
|
|
d67584629d | ||
|
|
c4fcbdd516 | ||
|
|
4e30fa0448 | ||
|
|
fd20f81885 | ||
|
|
cf0d54450a | ||
|
|
2728a73959 | ||
|
|
d41b113574 | ||
|
|
84799a5ec0 | ||
|
|
d153f26a06 | ||
|
|
82fcb82d92 | ||
|
|
5f66a0bdb1 | ||
|
|
6690688098 | ||
|
|
6d60391e0c | ||
|
|
6a2d5da5fe | ||
|
|
eb87e49e46 | ||
|
|
d699b1d2c0 | ||
|
|
ba03f218e6 | ||
|
|
1bca9371dc | ||
|
|
cb0a1d6d83 | ||
|
|
42449ee34e | ||
|
|
26331d1a2c | ||
|
|
cef5b26425 | ||
|
|
965fbf847b | ||
|
|
f91a1d2d5c | ||
|
|
90c78d4c47 | ||
|
|
510ebe09d6 | ||
|
|
7f5dbfdf30 | ||
|
|
1e41dde42c | ||
|
|
7630acffc6 | ||
|
|
f8f5a88ec6 | ||
|
|
d84b32fc92 | ||
|
|
6eff7e25a3 | ||
|
|
a57c719649 | ||
|
|
13c2500d0e | ||
|
|
c181163a75 | ||
|
|
8af3ae8af8 | ||
|
|
02a0cacd34 | ||
|
|
2b3235e6c9 | ||
|
|
0bc8ae07a2 | ||
|
|
ab7b0fb3a8 | ||
|
|
7b75fe934e | ||
|
|
8c7116b2d8 | ||
|
|
80e6f99862 | ||
|
|
188e80c2b2 | ||
|
|
04a5676403 | ||
|
|
2df81038f9 | ||
|
|
381a097045 | ||
|
|
c5df6ad58f | ||
|
|
6cb0257630 | ||
|
|
0970a3ef62 | ||
|
|
50b53c4221 | ||
|
|
bb446cb579 | ||
|
|
d590ccb7ad | ||
|
|
d90a61f176 | ||
|
|
444584ce19 | ||
|
|
ee87cab922 | ||
|
|
273d75b9fd | ||
|
|
f79954ccdd | ||
|
|
6497279b75 | ||
|
|
98f939da12 | ||
|
|
1e7b026f6d | ||
|
|
a8e7baacb8 | ||
|
|
c3eedabb04 | ||
|
|
e179e6f417 | ||
|
|
84084fc36a | ||
|
|
d95a01b9b5 | ||
|
|
b9bfd4fbb2 | ||
|
|
f14d94fe3e | ||
|
|
61a920e0a5 | ||
|
|
0239f10621 | ||
|
|
4c4accea28 | ||
|
|
0c4a46bea3 | ||
|
|
038106de17 | ||
|
|
2ff40924a2 | ||
|
|
0b81716c56 | ||
|
|
8a58341982 | ||
|
|
5007d0e8f2 | ||
|
|
6734e1cad9 | ||
|
|
2a13553544 | ||
|
|
4e5a3f4f80 | ||
|
|
dcebcdb6fe | ||
|
|
56772eeb6c | ||
|
|
82b51b7a36 | ||
|
|
fe3f0209da | ||
|
|
6c71f9bba8 | ||
|
|
b3802c0e85 | ||
|
|
d62c788cd7 | ||
|
|
21ff95e97b | ||
|
|
d5f7148511 | ||
|
|
1704c16c38 | ||
|
|
26c9f97223 | ||
|
|
97eea5bd87 | ||
|
|
271f73f7f9 | ||
|
|
4e155f4c3b | ||
|
|
2e12d9b473 | ||
|
|
889785c4ec | ||
|
|
60407e4170 | ||
|
|
127b2a80d2 | ||
|
|
87ffb81a65 | ||
|
|
4836e1e951 | ||
|
|
0cfbac1b43 | ||
|
|
7bc46324c2 | ||
|
|
10d3e1422c | ||
|
|
843344a9df | ||
|
|
76158af131 | ||
|
|
0a8f594bd5 | ||
|
|
520d12631b | ||
|
|
d8582f7814 | ||
|
|
73fbec166d | ||
|
|
24209635c4 | ||
|
|
196abf2a24 | ||
|
|
b2d27a1d7b | ||
|
|
406e112aaa | ||
|
|
2118d5b4dd | ||
|
|
65c13bba83 | ||
|
|
b6522e4dc0 | ||
|
|
31606d0dc8 | ||
|
|
33511fd105 | ||
|
|
0c7be074f5 | ||
|
|
3ebda28fed | ||
|
|
3a0ff1f94d | ||
|
|
50a02e3ba4 | ||
|
|
ab87e735ad | ||
|
|
6e6d1ef264 | ||
|
|
bf99c6236e | ||
|
|
ac95844ab3 | ||
|
|
c55caf4290 | ||
|
|
722a626e55 | ||
|
|
90a514d935 | ||
|
|
ded5251daf | ||
|
|
9b1d3b36fd | ||
|
|
b5a2291ec6 | ||
|
|
d2d2dede3f | ||
|
|
3a5e12b895 | ||
|
|
3ce65f69c1 | ||
|
|
3e8899c43e | ||
|
|
49fc92849c | ||
|
|
4ace667c53 | ||
|
|
894a462e4c | ||
|
|
dadd86056e | ||
|
|
07f455caf8 | ||
|
|
dd4b967fbf | ||
|
|
274b68baaa | ||
|
|
b99faba3cd | ||
|
|
a533bc0649 | ||
|
|
eeb89e6e14 | ||
|
|
6dec4afef8 | ||
|
|
57a6693de7 | ||
|
|
100d158ae5 | ||
|
|
3fcc3668f0 | ||
|
|
9f1dee5c74 | ||
|
|
6066df8ae4 | ||
|
|
a8b92a2211 | ||
|
|
7e433bf901 | ||
|
|
16155ed852 | ||
|
|
257349e6ed | ||
|
|
6b031d66bc | ||
|
|
11feffb1f6 | ||
|
|
87de937fdd | ||
|
|
1080a1dc83 | ||
|
|
c84d20cdbe | ||
|
|
276b2ada0c | ||
|
|
2c4ae35127 | ||
|
|
021dc55898 | ||
|
|
b199167eb2 | ||
|
|
c1e86507d8 | ||
|
|
08bcf2463f | ||
|
|
6062f6ff1e | ||
|
|
8691a731d5 | ||
|
|
c35796af7e | ||
|
|
61bbca23ff | ||
|
|
a082146715 | ||
|
|
6eb497770b | ||
|
|
03851157cf | ||
|
|
ba17eb6a31 | ||
|
|
a19163ddb3 | ||
|
|
6d67f1beaa | ||
|
|
947e21f9b2 | ||
|
|
afd4154ee7 | ||
|
|
68f6ee540c | ||
|
|
31c974c461 | ||
|
|
d4e7fdef7e | ||
|
|
e30fa91769 | ||
|
|
ef056583c8 | ||
|
|
c8be808eba | ||
|
|
5bde00223d | ||
|
|
9646f76f82 | ||
|
|
e1333c96b0 | ||
|
|
ac6b8b8592 | ||
|
|
70ea5ed597 | ||
|
|
dd9e3b60db | ||
|
|
6b023df258 | ||
|
|
d70c12e2a4 | ||
|
|
8f0c15e966 | ||
|
|
fdf88bfdd7 | ||
|
|
24e31f997c | ||
|
|
c53a4a0ce9 | ||
|
|
33aae30c92 | ||
|
|
d76e1ffc8f | ||
|
|
2d11fb414d | ||
|
|
e6943b8f78 | ||
|
|
d31d4424f6 | ||
|
|
bb26a270dc | ||
|
|
ba87fef3b2 | ||
|
|
4c181c9671 | ||
|
|
076df77563 | ||
|
|
07411bba40 | ||
|
|
24dfd4ae76 | ||
|
|
a9aca1b8ed | ||
|
|
b2ebfc0ecb | ||
|
|
eb0681f9c2 | ||
|
|
041b493a25 | ||
|
|
a81eb771e5 | ||
|
|
acf427974b | ||
|
|
c3475f194e | ||
|
|
6975781a0b | ||
|
|
665fe67aa6 | ||
|
|
5b149c7ff2 | ||
|
|
35477d9c06 | ||
|
|
576baf6fff | ||
|
|
f7e5b7f726 | ||
|
|
ca80c57797 | ||
|
|
7d2a4b155d | ||
|
|
29ad943f0a | ||
|
|
d4e7f25e3b | ||
|
|
e0ad44f2f1 | ||
|
|
ff68e0f66e | ||
|
|
08b8034eca | ||
|
|
d3385f8cd6 | ||
|
|
d51112e6af | ||
|
|
6bfb7c6d6e | ||
|
|
3c9792545b | ||
|
|
1c79bd2646 | ||
|
|
6bb5830220 | ||
|
|
7b7cf7e5e8 | ||
|
|
c79ac8ba19 | ||
|
|
89cb8d1d9c | ||
|
|
06672462ab | ||
|
|
6fd4f44125 | ||
|
|
f7172dd0c5 | ||
|
|
1c51c9fa5e | ||
|
|
a399cca7ce | ||
|
|
736317e684 | ||
|
|
3c0c054d62 | ||
|
|
3a07faf23a | ||
|
|
0bfa706a39 | ||
|
|
837267fb0a | ||
|
|
6a3c509768 | ||
|
|
31b4646882 | ||
|
|
16a5b00738 | ||
|
|
8d18dfbc3d | ||
|
|
e4870c94f2 | ||
|
|
241468ab7a | ||
|
|
94d7d2574b | ||
|
|
dd978169da | ||
|
|
ca81bdf71e | ||
|
|
84f56ec3b2 | ||
|
|
208117bdd3 | ||
|
|
d2155dc561 | ||
|
|
db66e1c3d4 | ||
|
|
113b49e283 | ||
|
|
b48189790c | ||
|
|
882219f962 | ||
|
|
8dfcdbed76 | ||
|
|
8017995ba3 | ||
|
|
ca399ffd0b | ||
|
|
bf67680f4b | ||
|
|
b24a0524ed | ||
|
|
a4c995a394 | ||
|
|
fb0d53a796 | ||
|
|
9deab33dc1 | ||
|
|
29adaf26e9 | ||
|
|
b3acc1390c | ||
|
|
3abc89b9e7 | ||
|
|
04560724d3 | ||
|
|
81aadc3e05 | ||
|
|
7c20c274d7 | ||
|
|
7339021684 | ||
|
|
579fb1bfa7 | ||
|
|
0859350715 | ||
|
|
4165fe221b | ||
|
|
d76454b1ec | ||
|
|
50924f296f | ||
|
|
0a689b5008 | ||
|
|
ac1ac4d5b1 | ||
|
|
53ffb11a21 | ||
|
|
348d1c5b8a | ||
|
|
434fb6e9fa | ||
|
|
90094b6b9a | ||
|
|
4f2f4f6a60 | ||
|
|
1210db9a15 | ||
|
|
94358489ef | ||
|
|
06398da4df | ||
|
|
504720e366 | ||
|
|
3d7892c2e6 | ||
|
|
170739e662 | ||
|
|
07de257371 | ||
|
|
6e2238f231 | ||
|
|
f640ffd251 | ||
|
|
0401ad96e5 | ||
|
|
05cd507d9a | ||
|
|
3e90724505 | ||
|
|
efb91874f8 | ||
|
|
4e8d58869e | ||
|
|
32efd30dc0 | ||
|
|
eec4c8cf85 | ||
|
|
ebdcca4fa8 | ||
|
|
d38f390b95 | ||
|
|
e3cdb76373 | ||
|
|
d5e3cad80e | ||
|
|
2287e0caf2 | ||
|
|
b8a357b685 | ||
|
|
ff5bf153bf | ||
|
|
dde7ff4c45 | ||
|
|
1cf1f435a6 | ||
|
|
4e40cad235 | ||
|
|
14c1d461b7 | ||
|
|
07c4604c9b | ||
|
|
ef755f3ad3 | ||
|
|
e19ecf71da | ||
|
|
7c62bd8871 | ||
|
|
6c52269dc5 | ||
|
|
736a3e4610 | ||
|
|
ae34b77371 | ||
|
|
946a46f2b1 | ||
|
|
1e87b50998 | ||
|
|
f59a228daf | ||
|
|
db3a412c8a | ||
|
|
202f96876e | ||
|
|
2489d5e234 | ||
|
|
64ad2ba20c | ||
|
|
60c4e1b007 | ||
|
|
6e3b4fdd7b | ||
|
|
d7b40e1052 | ||
|
|
8e412f08bc | ||
|
|
62a8f72b98 | ||
|
|
aaec6c4ca1 | ||
|
|
89441ac126 | ||
|
|
9a6dad11bc | ||
|
|
d9f7842aec | ||
|
|
65762b1dce | ||
|
|
ba24811356 | ||
|
|
573d52119a | ||
|
|
3cafacc3e9 | ||
|
|
f511c267ce | ||
|
|
799fbf43d1 | ||
|
|
c4b075b1c8 | ||
|
|
8112ddfec2 | ||
|
|
5a1708185a | ||
|
|
35e2af7711 | ||
|
|
a805b53d86 | ||
|
|
c0c59320a5 | ||
|
|
388ec98087 | ||
|
|
271bfcfb31 | ||
|
|
2be1fb5123 | ||
|
|
70b0c06349 | ||
|
|
bd7d8c944c | ||
|
|
355adf8369 | ||
|
|
c9ce7af0f2 | ||
|
|
086aa43055 | ||
|
|
103bd6475f | ||
|
|
5cc94532a7 | ||
|
|
e07ed0bd9c | ||
|
|
391add0945 | ||
|
|
cf576055f6 | ||
|
|
0d84e72d76 | ||
|
|
4932eef1c9 | ||
|
|
c6a00c1a71 | ||
|
|
a67a077906 | ||
|
|
798a4bb2b9 | ||
|
|
eb07e2b058 | ||
|
|
a878472a73 | ||
|
|
ef508b4223 | ||
|
|
df7f31098c | ||
|
|
fa9524f9c9 | ||
|
|
1368f059bb | ||
|
|
8701060355 | ||
|
|
ee067ed3f2 | ||
|
|
b57dedb74a | ||
|
|
d7c13adac0 | ||
|
|
bd2473a7bf | ||
|
|
de16cb71f1 | ||
|
|
4995844f04 | ||
|
|
ffc431753b | ||
|
|
67f887d870 | ||
|
|
5a337fd6c1 | ||
|
|
b71ecc1c24 | ||
|
|
71bd19d5df | ||
|
|
28de82e63c | ||
|
|
b4709f5db5 | ||
|
|
b0dccc0f81 | ||
|
|
6c65266f05 | ||
|
|
6ffe2f1af2 | ||
|
|
5f26d02433 | ||
|
|
68ce0cf25f | ||
|
|
0b638884f7 | ||
|
|
b704dc50c3 | ||
|
|
62b6d6def2 | ||
|
|
8d886eedfe | ||
|
|
7cff8ddbd3 | ||
|
|
9d1eed6a82 | ||
|
|
eeadc829b9 | ||
|
|
efe040549c | ||
|
|
5bc9e65cdd | ||
|
|
d6a604051f | ||
|
|
51a03b30f2 | ||
|
|
561f3b2fbf | ||
|
|
3a7af2c8fe | ||
|
|
26c7c362d2 | ||
|
|
0642ea52c9 | ||
|
|
957e33207e | ||
|
|
a39fe345b5 | ||
|
|
40e72ddb8c | ||
|
|
195c3fd75d | ||
|
|
c626bccad3 | ||
|
|
e295188075 | ||
|
|
7804e1bd59 | ||
|
|
2870007392 | ||
|
|
fc9d442599 | ||
|
|
f4321dd3d6 | ||
|
|
d76416f03c | ||
|
|
6b6889b8b4 | ||
|
|
070e4b5c50 | ||
|
|
f809c119bd | ||
|
|
a806dc920f | ||
|
|
74fc02b2cc | ||
|
|
c1fc987d96 | ||
|
|
7f97a61ed5 | ||
|
|
94e8c5196c | ||
|
|
39b1c0fe0d | ||
|
|
6f2fc1deae | ||
|
|
a2d8f0639c | ||
|
|
91808bb042 | ||
|
|
25337dd440 | ||
|
|
ec25771453 | ||
|
|
c544f4aef6 | ||
|
|
0ce21c4b15 | ||
|
|
ce4d560dc1 | ||
|
|
87e98edd61 | ||
|
|
61513287ce | ||
|
|
8011b66e53 | ||
|
|
ea8a62ab8e | ||
|
|
5358b5ba10 | ||
|
|
1f7f5f90dc | ||
|
|
14fc7f1ae0 | ||
|
|
c58ae8be21 | ||
|
|
c568ded7c9 | ||
|
|
0717767297 | ||
|
|
10fc74c0ec | ||
|
|
c9e7d81e8e | ||
|
|
312a1d70f7 | ||
|
|
d1bc20ac33 | ||
|
|
031355790f | ||
|
|
49fdcae8c2 | ||
|
|
56395596e5 | ||
|
|
c511440ed9 | ||
|
|
8f4ff0e166 | ||
|
|
6775e76e5f | ||
|
|
b9a479607c | ||
|
|
05a3db3cc0 | ||
|
|
145b7ce69a | ||
|
|
c6fa162728 | ||
|
|
527dc2cc48 | ||
|
|
7672ee3666 | ||
|
|
7ca4f33dcf | ||
|
|
78e4cb4410 | ||
|
|
5cfe0f077f | ||
|
|
baa50c136a | ||
|
|
fa9a8bbf95 | ||
|
|
24d0bedf7d | ||
|
|
8aeca9c2a8 | ||
|
|
38b8786ede | ||
|
|
146513aeb0 | ||
|
|
81c6ece801 | ||
|
|
4dc5088fb2 | ||
|
|
4c53fd2bf6 | ||
|
|
885425e2a3 | ||
|
|
b74c77b74f | ||
|
|
1bc8e8fd3a | ||
|
|
6dbdb1d8ed | ||
|
|
ea5585e381 | ||
|
|
ace95a3355 | ||
|
|
019615f376 | ||
|
|
a8d40afd58 | ||
|
|
1e0e078c17 | ||
|
|
ebe3800c75 | ||
|
|
30b98bea85 | ||
|
|
d9738a7ee5 | ||
|
|
d778b938e7 | ||
|
|
e7b91c0a85 | ||
|
|
5e9fa908b4 | ||
|
|
91808c5fd9 | ||
|
|
0784b1ee19 | ||
|
|
b3cdd72754 | ||
|
|
9d2964ee7d | ||
|
|
4a8913f7ea | ||
|
|
8fbd73af1e | ||
|
|
1be2b2c295 | ||
|
|
02778fd670 | ||
|
|
985f014f40 | ||
|
|
2a63d07146 | ||
|
|
947d30c5c4 | ||
|
|
e71ce3395d | ||
|
|
f5e7be25dd | ||
|
|
ded32cd66a | ||
|
|
c8d024c25f | ||
|
|
b519ad8d18 | ||
|
|
fcb1f5dc54 | ||
|
|
9b7a2f93ad | ||
|
|
9ce253b644 | ||
|
|
5a9d24044f | ||
|
|
b853da673c | ||
|
|
d56b5abde2 | ||
|
|
24cbbb9a11 | ||
|
|
ed57c8f0fa | ||
|
|
07b99704ee | ||
|
|
9440e4d153 | ||
|
|
1e1ade3cbd | ||
|
|
1840647458 | ||
|
|
7471dcd3bf | ||
|
|
c3114e65bf | ||
|
|
c2aa60f292 | ||
|
|
96fb8d280e | ||
|
|
e4e29e1316 | ||
|
|
63f975ad43 | ||
|
|
a01fc5b758 | ||
|
|
a3953fba65 | ||
|
|
481e31220b | ||
|
|
040ce4db81 | ||
|
|
488075de9b | ||
|
|
8fb89b25d9 | ||
|
|
099c9024bb | ||
|
|
bd7e75f4b3 | ||
|
|
a358764b9a | ||
|
|
b3d61a6de7 | ||
|
|
0bfd86880b | ||
|
|
e5b14e4177 | ||
|
|
e9f0112e28 | ||
|
|
0de86d3faf | ||
|
|
aa2159b7e5 | ||
|
|
894cfc2acd | ||
|
|
1c30c24639 | ||
|
|
7e37e0dac0 | ||
|
|
cd177ab0b1 | ||
|
|
cd2ed8eeee | ||
|
|
c7a084aa25 | ||
|
|
6952d1ab48 | ||
|
|
112a3e27a6 | ||
|
|
bbac5a730f | ||
|
|
348c96bf13 | ||
|
|
fd783734ac | ||
|
|
fc4f375a65 | ||
|
|
1d6b47ceef | ||
|
|
cda1c876b2 | ||
|
|
6112ea2558 | ||
|
|
57ecd0ec10 | ||
|
|
37129671b6 | ||
|
|
97f1655ff7 | ||
|
|
3c409d3bc1 | ||
|
|
1cf509c365 | ||
|
|
6b530b0269 | ||
|
|
e525ab7d64 | ||
|
|
12c7ae1e05 | ||
|
|
31d19fd51a | ||
|
|
74540e9f4d | ||
|
|
afc8a99d7e | ||
|
|
859a79ad35 | ||
|
|
130dfb6358 | ||
|
|
6ab27328cc | ||
|
|
72c31ca524 | ||
|
|
4d69941593 | ||
|
|
91f22b502f | ||
|
|
0d19a55ddd | ||
|
|
ceef16f0c8 | ||
|
|
187f34dfee | ||
|
|
96b1e40c0a | ||
|
|
63d77a8b81 | ||
|
|
8022342e81 | ||
|
|
6379e15ce1 | ||
|
|
5b075623ff | ||
|
|
46cbaa053c | ||
|
|
0a423fc433 | ||
|
|
ffc33b4c69 | ||
|
|
1d3773ab5e | ||
|
|
a968b4bec8 | ||
|
|
65902d11e4 | ||
|
|
050dc31c97 | ||
|
|
aae96faa76 | ||
|
|
0dea44acf4 | ||
|
|
b158f6f2b7 | ||
|
|
11da3d4e3c | ||
|
|
5f4fc247a4 | ||
|
|
78ba3c5394 | ||
|
|
781fa3ea0c | ||
|
|
a08b661af6 | ||
|
|
068b236eba | ||
|
|
726fa3910d | ||
|
|
d0009ba05a | ||
|
|
e2a19ce086 | ||
|
|
ab9b5ba3ec | ||
|
|
3b4ed6c0a4 | ||
|
|
70d39aae7b | ||
|
|
56ccc46f5f | ||
|
|
ff33905704 | ||
|
|
69739420fa | ||
|
|
2b593bc742 | ||
|
|
eb1b7baf1c | ||
|
|
05eef0e8f5 | ||
|
|
c2c634707e | ||
|
|
0579b326be | ||
|
|
70a26fec26 | ||
|
|
02ec9bb98e | ||
|
|
b2f608b884 | ||
|
|
a496dc8170 | ||
|
|
8ad15399d6 | ||
|
|
8e11514e7c | ||
|
|
89cb5573d9 | ||
|
|
23ebd6ac08 | ||
|
|
5856d76e65 | ||
|
|
86b1f6ede3 | ||
|
|
68f13c4985 | ||
|
|
3f4783dfab | ||
|
|
03df8cbf43 | ||
|
|
572305d7c8 | ||
|
|
2aa93abc0f | ||
|
|
0be3d23369 | ||
|
|
e2954d0117 | ||
|
|
497b95ec64 | ||
|
|
02e7594de5 | ||
|
|
7efa68e853 | ||
|
|
003fefa61d | ||
|
|
619580afe5 | ||
|
|
5c035768b0 | ||
|
|
9a878b0fbd | ||
|
|
779b026e6b | ||
|
|
ccae4e4ce2 | ||
|
|
a7675470ab | ||
|
|
d39a22945b | ||
|
|
aac7799e3e | ||
|
|
63b2916993 | ||
|
|
310f558e9c | ||
|
|
1a0428da97 | ||
|
|
4783b07407 | ||
|
|
0334c5a289 | ||
|
|
12a9a2e485 | ||
|
|
7f7cdccb6b | ||
|
|
f9424231a9 | ||
|
|
d4ba70db5c | ||
|
|
a59f5e1c4f | ||
|
|
02316d4ee0 | ||
|
|
4f148de74d | ||
|
|
9f10d5207f | ||
|
|
484bde10b3 | ||
|
|
8281757da8 | ||
|
|
4e25e2eb81 | ||
|
|
f552426304 | ||
|
|
c046901d8f | ||
|
|
3bfc90a8bb | ||
|
|
15295dd294 | ||
|
|
1405a1894b | ||
|
|
a1c8cfe967 | ||
|
|
f0b424c84f | ||
|
|
582746587b | ||
|
|
a69fe71406 | ||
|
|
13155ce64c | ||
|
|
c5d95ca805 | ||
|
|
52ee7c8700 | ||
|
|
cfb314198a | ||
|
|
74ff65954f | ||
|
|
0b2fc81be4 | ||
|
|
9e180b8ba7 | ||
|
|
e08a6e8a48 | ||
|
|
7d06c140fa | ||
|
|
d914406c84 | ||
|
|
31a3ff61e8 | ||
|
|
3773047a06 | ||
|
|
72b7ee2480 | ||
|
|
a1d089038d | ||
|
|
562e604cee | ||
|
|
71c906b00b | ||
|
|
6d22a407cc | ||
|
|
bdfbe3a87e | ||
|
|
18ec564249 | ||
|
|
cb3613db71 | ||
|
|
7dbfe15d1a | ||
|
|
92277a01ac | ||
|
|
ccf8f86c8d | ||
|
|
7425f974cb | ||
|
|
73f3345638 | ||
|
|
302f805295 | ||
|
|
58e62ebd06 | ||
|
|
0de72d2dad | ||
|
|
7898ad772b | ||
|
|
25a1881127 | ||
|
|
34350cb7ec | ||
|
|
e130ec03ad | ||
|
|
0cd544b4ce | ||
|
|
6362be8196 | ||
|
|
aa4d9d62bc | ||
|
|
cd44a52084 | ||
|
|
98fd3c7379 | ||
|
|
7cfbcbd9e2 | ||
|
|
73b5609e63 | ||
|
|
fe06370aa2 | ||
|
|
a1b1a7d702 | ||
|
|
ccdf0d9f95 | ||
|
|
8d1a82f9b4 | ||
|
|
287ce9c0ff | ||
|
|
b8ed846247 | ||
|
|
2a9a62d0f6 | ||
|
|
16dc2f63f1 | ||
|
|
377bccf12a | ||
|
|
030a8e7111 | ||
|
|
189d926c6a | ||
|
|
d993fe217c | ||
|
|
8983c9bce1 | ||
|
|
ced1f36d19 | ||
|
|
e698fa664b | ||
|
|
ab2cf59bf6 | ||
|
|
a315ac9e54 | ||
|
|
c6347ec9c8 | ||
|
|
ac8379af29 | ||
|
|
69622e909b | ||
|
|
910167de09 | ||
|
|
29fb58de84 | ||
|
|
dbf17dea18 | ||
|
|
7fcbc0fd5a | ||
|
|
32c79b7a91 | ||
|
|
1647fc3017 | ||
|
|
17f43fd138 | ||
|
|
a708ceefe8 | ||
|
|
1f12902f78 | ||
|
|
cebbcf592e | ||
|
|
0c7994c502 | ||
|
|
d412df5883 | ||
|
|
cca3744396 | ||
|
|
c98c50291c | ||
|
|
e9035ab3e0 | ||
|
|
d8eb4432b9 | ||
|
|
e430b90cea | ||
|
|
08a1f07692 | ||
|
|
8dcf544079 | ||
|
|
98cbf2f47f | ||
|
|
e041d87b5a | ||
|
|
5440aca212 | ||
|
|
834980eae7 | ||
|
|
a61822f9c9 | ||
|
|
6290859f81 | ||
|
|
62408af5ea | ||
|
|
711a8f0aae | ||
|
|
382988a06a | ||
|
|
88431bdbea | ||
|
|
62cb0ae28f | ||
|
|
31f5a2bb73 | ||
|
|
cb90cd9929 | ||
|
|
d402587ab2 | ||
|
|
02226f938e | ||
|
|
37309218ec | ||
|
|
03740f1369 | ||
|
|
d3314447a8 | ||
|
|
4b4bfbe1b1 | ||
|
|
a8b170f51c | ||
|
|
a669a309f6 | ||
|
|
a628ba1b8f | ||
|
|
5bf87c4da1 | ||
|
|
b7c5b24d43 | ||
|
|
44bb4f2cc3 | ||
|
|
55a58eaf30 | ||
|
|
5d3ca843b6 | ||
|
|
ecf12aa0e7 | ||
|
|
427770a6d0 | ||
|
|
2d9604918a | ||
|
|
567a6c4a9f | ||
|
|
31b617b10f | ||
|
|
a6fe648a41 | ||
|
|
66163bee2b | ||
|
|
db7d352c97 | ||
|
|
cda92f4ba3 | ||
|
|
133613aeb1 | ||
|
|
15e01dfe5d | ||
|
|
6df7190472 | ||
|
|
5212d138f8 | ||
|
|
465582d20c | ||
|
|
fae60e9fae | ||
|
|
c89645e069 | ||
|
|
6465cf4f3e | ||
|
|
54c052c5eb | ||
|
|
465b8273eb | ||
|
|
129e0ce4b5 | ||
|
|
309b280d0d | ||
|
|
99d9b17a2d | ||
|
|
208a741823 | ||
|
|
c953d59b5a | ||
|
|
c0fefc4d1a | ||
|
|
0fcc979fe1 | ||
|
|
cb9d9bd8a1 | ||
|
|
1d5a68c9e7 | ||
|
|
8e3f45b899 | ||
|
|
ea87b9bfc2 | ||
|
|
df91ff7735 | ||
|
|
652fe97a1b | ||
|
|
06565765b8 | ||
|
|
fc9c7dcdfc | ||
|
|
72f1ce9096 | ||
|
|
0abf69dc1d | ||
|
|
a4f30ebf1d | ||
|
|
ed137a93ce | ||
|
|
e73ee5f690 | ||
|
|
de886d6c3d | ||
|
|
050d5f898f | ||
|
|
e3341a19cd | ||
|
|
8f5e3ad7c0 | ||
|
|
384c9b9725 | ||
|
|
981fa5db9a | ||
|
|
c417a9a55e | ||
|
|
52ab4d3ecd | ||
|
|
62bc2758eb | ||
|
|
731c8bf0fd | ||
|
|
d78da7b994 | ||
|
|
c795bd16a7 | ||
|
|
7237275f5d | ||
|
|
3e7b196950 | ||
|
|
919c8fa72a | ||
|
|
bcb97bce1c | ||
|
|
64d8883210 | ||
|
|
0af99769ad | ||
|
|
c8fded80d5 | ||
|
|
c6a3157fd8 | ||
|
|
8afb02cf03 | ||
|
|
675e4c1031 | ||
|
|
d21d03b738 | ||
|
|
ff70c08fb9 | ||
|
|
506a9a44af | ||
|
|
10e8634d38 | ||
|
|
a1577127b7 | ||
|
|
5a1f1d2c64 | ||
|
|
a915651797 | ||
|
|
133d054fc8 | ||
|
|
c87f6ca983 | ||
|
|
a2e1836e24 | ||
|
|
53649f6020 | ||
|
|
601e220411 | ||
|
|
ed6c4b1925 | ||
|
|
46ee0ce161 | ||
|
|
71b3110acf | ||
|
|
e6f2db70ef | ||
|
|
65829c437c | ||
|
|
f27defbdf4 | ||
|
|
41bf8eadfd | ||
|
|
d76bd84466 | ||
|
|
ca244c5dbb | ||
|
|
ff0ac568f4 | ||
|
|
5d0b2fae86 | ||
|
|
f8a8b3cf31 | ||
|
|
88396411f7 | ||
|
|
42931f9300 | ||
|
|
a5bd17c0c0 | ||
|
|
a5e5f81d88 | ||
|
|
66da2d8f48 | ||
|
|
b619ee00bf | ||
|
|
899d8bc24d | ||
|
|
bf586ba2cb | ||
|
|
22248dd9e9 | ||
|
|
6dfc7a815b | ||
|
|
b27ba0434a | ||
|
|
3b41b5e15f | ||
|
|
8029deb1e4 | ||
|
|
5ee9990d93 | ||
|
|
8a9c5fe4a1 | ||
|
|
45d769b05b | ||
|
|
af032476a8 | ||
|
|
c52309ad59 | ||
|
|
8526371d25 | ||
|
|
7f4a6fd94c | ||
|
|
6fc5d1aea3 | ||
|
|
1860b26491 | ||
|
|
fccbe1aff4 | ||
|
|
fa45a9f3a4 | ||
|
|
98cd592f3e | ||
|
|
64b81ff5a4 | ||
|
|
f3deb04521 | ||
|
|
ab454f1e1b | ||
|
|
bd6d732fc7 | ||
|
|
4eac8a5a47 | ||
|
|
82dd2ebd05 | ||
|
|
1cd194a1e1 | ||
|
|
f26a5554d5 | ||
|
|
c380039b3e | ||
|
|
9125f54897 | ||
|
|
08fe5a89e9 | ||
|
|
2e46bdf9d2 | ||
|
|
18b9c46a8b | ||
|
|
a99e23f9fc | ||
|
|
8b089222bd | ||
|
|
5b25c9ad1a | ||
|
|
ec80797694 | ||
|
|
8b7d6848b3 | ||
|
|
edb14e2a6b | ||
|
|
6a82644153 | ||
|
|
ac3401bc4f | ||
|
|
9da71b1655 | ||
|
|
ed31004aa8 | ||
|
|
fe50674c8e | ||
|
|
1fe1ea58f6 | ||
|
|
b3f1a30027 | ||
|
|
111a95d262 | ||
|
|
35528a7199 | ||
|
|
927b753262 | ||
|
|
8359016981 | ||
|
|
5372fe9d6e | ||
|
|
8814da3b78 | ||
|
|
2d748bf63c | ||
|
|
eff1f0d77a | ||
|
|
aec8ec43ef | ||
|
|
93cd1e7a4a | ||
|
|
ea4e5d76e0 | ||
|
|
e6298f8107 | ||
|
|
704a874e84 | ||
|
|
428ed6c88c | ||
|
|
dd62879b7b | ||
|
|
14a31cd5f8 | ||
|
|
8a7df36d88 | ||
|
|
fe56d96295 | ||
|
|
fabf90bed4 | ||
|
|
c3a84f1b73 | ||
|
|
5a5a1aaa7f | ||
|
|
aef753a3a0 | ||
|
|
08028db982 | ||
|
|
85b2fe37e2 | ||
|
|
81959b5ef3 | ||
|
|
657d9bb8e8 | ||
|
|
2dfee97563 | ||
|
|
7f075d11ee | ||
|
|
a38b7b71ac | ||
|
|
139ab95438 | ||
|
|
71ac67f9f1 | ||
|
|
0e1b856fc5 | ||
|
|
0235d77932 | ||
|
|
6e1ca54edc | ||
|
|
274213bc83 | ||
|
|
5a42cb1b2b | ||
|
|
ee99efba36 | ||
|
|
b16a95d0f2 | ||
|
|
2c8bac5666 | ||
|
|
8e6b643829 | ||
|
|
cc24d00fde | ||
|
|
ddc1069e86 | ||
|
|
c9704d3c97 | ||
|
|
34775eb8db | ||
|
|
90d6490fea | ||
|
|
acb9e5ebdf | ||
|
|
12fff7c97f | ||
|
|
acb12ea7d4 | ||
|
|
e94c35d331 | ||
|
|
a685a72660 | ||
|
|
4aaa7d0555 | ||
|
|
2f09aa291b | ||
|
|
bdf2f25259 | ||
|
|
5a0af27115 | ||
|
|
18c4bc060b | ||
|
|
d23aa67f7b | ||
|
|
5a127d0700 | ||
|
|
aa160940df | ||
|
|
c8829f2aa4 | ||
|
|
0985c8f092 | ||
|
|
279edf0665 | ||
|
|
50fac81a30 | ||
|
|
99b86e7a29 | ||
|
|
151e021ef9 | ||
|
|
dd97b6a4b7 | ||
|
|
f30e8b7b46 | ||
|
|
ba3923d706 | ||
|
|
622cc83204 | ||
|
|
8e18c3d3b6 | ||
|
|
0adbd5662f | ||
|
|
f00d1159c8 | ||
|
|
4c90ce437e | ||
|
|
e109093b83 | ||
|
|
4ba3411292 | ||
|
|
8e1be54759 | ||
|
|
be6f2634b5 | ||
|
|
7191e820a2 | ||
|
|
9eed249028 | ||
|
|
bbff2b24d0 | ||
|
|
b91fa734d2 | ||
|
|
302eae6aeb | ||
|
|
088afa6d71 | ||
|
|
5f96c415e3 | ||
|
|
6c9fa68d5a | ||
|
|
bc4f5a3788 | ||
|
|
f094ecfd88 | ||
|
|
13268f7c63 | ||
|
|
aa820ce347 | ||
|
|
6310059531 | ||
|
|
6f92859608 | ||
|
|
758ff920fc | ||
|
|
7ba8063940 | ||
|
|
61de118130 | ||
|
|
4bf64f7005 | ||
|
|
85eab87dce | ||
|
|
5ba0cc5860 | ||
|
|
08aae5be3b | ||
|
|
071bad218a | ||
|
|
027e7fc5c6 | ||
|
|
498e8a1486 | ||
|
|
09c6bc1d12 | ||
|
|
62521f38e8 | ||
|
|
a6785afa5a | ||
|
|
7ebb46a092 | ||
|
|
a9fcc0a002 | ||
|
|
08ed3c7fc4 | ||
|
|
3c1a23e7b1 | ||
|
|
c7403361fd | ||
|
|
d9efb0a84d | ||
|
|
4f81255970 | ||
|
|
e556ef84a4 | ||
|
|
9587003d44 | ||
|
|
8f7ea41fe8 | ||
|
|
b4284d18d5 | ||
|
|
048d401309 | ||
|
|
85a1f3ec20 | ||
|
|
959b007269 | ||
|
|
9b550f7293 | ||
|
|
dc26b1efa8 | ||
|
|
d356e57134 | ||
|
|
c5b0ffe310 | ||
|
|
1ffa7825ed | ||
|
|
d95f3cd1c5 | ||
|
|
6ba64d97c8 | ||
|
|
fa508a2c7e | ||
|
|
d04df564f0 | ||
|
|
5f192dd6ce | ||
|
|
6819922d26 | ||
|
|
ec726e863c | ||
|
|
610754981b | ||
|
|
485034dec0 | ||
|
|
9316124733 | ||
|
|
1b9d91dc1e | ||
|
|
15550e1855 | ||
|
|
43adc84dfd | ||
|
|
8d6aeebb61 | ||
|
|
1c8c0cfbf0 | ||
|
|
047e25f7f7 | ||
|
|
258e53a402 | ||
|
|
c8c4dfba6e | ||
|
|
0bed544188 | ||
|
|
3cc07d36a2 | ||
|
|
78b53a5215 | ||
|
|
886382f568 | ||
|
|
a9dd1b4568 | ||
|
|
323243f1ec | ||
|
|
25366c2a37 | ||
|
|
b98c9ebc1d | ||
|
|
cb44cd2e33 | ||
|
|
1fefd410be | ||
|
|
f5bb5ff9c1 | ||
|
|
e2e7c490db | ||
|
|
68cf346025 | ||
|
|
7927372b75 | ||
|
|
ca2c9018c6 | ||
|
|
9ed5621a78 | ||
|
|
58cf528463 | ||
|
|
4602fc1105 | ||
|
|
b9e2a1b21e | ||
|
|
f76f294f7f | ||
|
|
64fff7edd2 | ||
|
|
beb84dbe07 | ||
|
|
d9768b5378 | ||
|
|
34befdf1d2 | ||
|
|
21df6e43a3 | ||
|
|
bc7b8367a9 | ||
|
|
c7a6720593 | ||
|
|
cf0c3bda92 | ||
|
|
2db2a033ab | ||
|
|
cf72184883 | ||
|
|
62344dccda | ||
|
|
03caa1b8ce | ||
|
|
97c8f4c026 | ||
|
|
674e45f473 | ||
|
|
36fec07a17 | ||
|
|
0c694a018c | ||
|
|
f37b513f21 | ||
|
|
56c7466e64 | ||
|
|
519be4db06 | ||
|
|
4255c5578b | ||
|
|
5e698278a8 | ||
|
|
b09b0bcdbd | ||
|
|
909a51000f | ||
|
|
306b43624b | ||
|
|
ec22c23bc5 | ||
|
|
a4ba11eabb | ||
|
|
58559aff16 | ||
|
|
3e3511ac44 | ||
|
|
36ae029c18 | ||
|
|
4dc016f3e5 | ||
|
|
d90e99216b | ||
|
|
67838807e8 | ||
|
|
dc2cdd55c0 | ||
|
|
5b0f6013e8 | ||
|
|
52c956831e | ||
|
|
4f93897b71 | ||
|
|
5676c8f753 | ||
|
|
eed72600c5 | ||
|
|
35ca9691d2 | ||
|
|
072f7760a4 | ||
|
|
3c1599a1f4 | ||
|
|
90808124f5 | ||
|
|
3c96fcc888 | ||
|
|
d21a7ef8e2 | ||
|
|
b1ec12af43 | ||
|
|
7929dfec0f | ||
|
|
8bb223f6e3 | ||
|
|
8b911e6074 | ||
|
|
10a3d1df69 | ||
|
|
8cf581d496 | ||
|
|
0095ba8984 | ||
|
|
6f32aa95a7 | ||
|
|
afb43c5883 | ||
|
|
85ef54a9a1 | ||
|
|
2f581a1181 | ||
|
|
110f872779 | ||
|
|
54931afa8b | ||
|
|
2bdd2dab78 | ||
|
|
2908323702 | ||
|
|
5d37bfe2fa | ||
|
|
0b0bdb17aa | ||
|
|
e5b2ae967b | ||
|
|
c03ae0ab47 | ||
|
|
5d664cd00d | ||
|
|
00ed67f1b7 | ||
|
|
277ded519d | ||
|
|
7835c4047b | ||
|
|
ab0af4554c | ||
|
|
926414a014 | ||
|
|
3991c8c5f7 | ||
|
|
cb4d60ca8d | ||
|
|
7ebe1977d8 | ||
|
|
5e9c71e0e3 | ||
|
|
723287b305 | ||
|
|
46b2e45fd5 | ||
|
|
390999e042 | ||
|
|
8a7e165214 | ||
|
|
5742f5e811 | ||
|
|
52b6578fcf | ||
|
|
2f205f20c5 | ||
|
|
e1df7c3b4d | ||
|
|
7c2f806745 | ||
|
|
6877f0898f | ||
|
|
74ac6eae8f | ||
|
|
75610e92a7 | ||
|
|
7dc8b86001 | ||
|
|
dfbfcfecc7 | ||
|
|
7ac81f8fd5 | ||
|
|
fd36a0cc72 | ||
|
|
398c5aa009 | ||
|
|
7a90c0cd88 | ||
|
|
cfcca5f881 | ||
|
|
ca67265c79 | ||
|
|
b422fe297c | ||
|
|
856c47138a | ||
|
|
83cdf647c9 | ||
|
|
ff46a7dc50 | ||
|
|
9e479481cc | ||
|
|
532627fad2 | ||
|
|
aa23660d0c | ||
|
|
20db868592 | ||
|
|
02948657a4 | ||
|
|
050c66250c | ||
|
|
88ce4fe81b | ||
|
|
e819dd39ca | ||
|
|
cfb13ac59f | ||
|
|
00aee4be00 | ||
|
|
a669975fb0 | ||
|
|
161d719dba | ||
|
|
ccc75f2978 | ||
|
|
8b0598abee | ||
|
|
31598b4329 | ||
|
|
dd220458f8 | ||
|
|
d4163dde8e | ||
|
|
3bd563e495 | ||
|
|
525c5852fb | ||
|
|
69501bd110 | ||
|
|
95e086a543 | ||
|
|
f6cd2d279d | ||
|
|
9cab69a968 | ||
|
|
6906c7ba55 | ||
|
|
243c13b7ee | ||
|
|
09cc1f2db0 | ||
|
|
7d295bdc8b | ||
|
|
b6807fc264 | ||
|
|
b3ef770819 | ||
|
|
726f355e9c | ||
|
|
ad7e341b78 | ||
|
|
53a3076e1c | ||
|
|
02d935dbaa | ||
|
|
4507d1d46d | ||
|
|
2566707256 | ||
|
|
6b1113e355 | ||
|
|
de45269ec3 | ||
|
|
479a976459 | ||
|
|
332b5605d6 | ||
|
|
c3d16ddb30 | ||
|
|
b6fa67c49f | ||
|
|
1c7c96a245 | ||
|
|
0da6f27aac | ||
|
|
b5f8c73060 | ||
|
|
5e2db65383 | ||
|
|
fc08b55eac | ||
|
|
8229eb657e | ||
|
|
1c532d9637 | ||
|
|
c743ba893c | ||
|
|
a5eb3b6012 | ||
|
|
2d6306644c | ||
|
|
711f095ebc | ||
|
|
0705c9f540 | ||
|
|
1e52fe2749 | ||
|
|
65e7650b16 | ||
|
|
cc16a7a741 | ||
|
|
9d3f2d0cfd | ||
|
|
0cc3fe6ab4 | ||
|
|
9e03342690 | ||
|
|
8501969643 | ||
|
|
0f5d8ec2a6 | ||
|
|
7c084f855f | ||
|
|
af26f0f41e | ||
|
|
1c0e44cc8e | ||
|
|
e0ae584ea7 | ||
|
|
ab056f3190 | ||
|
|
16e827f3ba | ||
|
|
4fd36592dc | ||
|
|
4a1e637b83 | ||
|
|
d19a6f2615 | ||
|
|
c3f1210619 | ||
|
|
56fddcc5e2 | ||
|
|
2567e60834 | ||
|
|
315e3487a9 | ||
|
|
f040726478 | ||
|
|
27bb2cf826 | ||
|
|
2ff2ce4de4 | ||
|
|
69fd8e7eed | ||
|
|
66387a15b7 | ||
|
|
a0c1b4c05d | ||
|
|
d5252375e1 | ||
|
|
880efd1843 | ||
|
|
9823d07817 | ||
|
|
2b58487ad7 | ||
|
|
2c502e3997 | ||
|
|
32d481df26 | ||
|
|
b084eb03ff | ||
|
|
043a965db3 | ||
|
|
65b4b0310b | ||
|
|
5d50a773e7 | ||
|
|
c399f1117b | ||
|
|
d9327a02a2 | ||
|
|
617ecf11ec | ||
|
|
83caebf384 | ||
|
|
d3cba4d80e | ||
|
|
654ea7094c | ||
|
|
52a3974a78 | ||
|
|
cbd398d7f6 | ||
|
|
12f3edd4ab | ||
|
|
76f292a6ba | ||
|
|
9ce9d670c9 | ||
|
|
4888299b28 | ||
|
|
e4f3428344 | ||
|
|
c4e879ea96 | ||
|
|
83235b13c1 | ||
|
|
5de52b96f4 | ||
|
|
2aedd9b27b | ||
|
|
ea1a4c5add | ||
|
|
88864153eb | ||
|
|
9ad3d21b75 | ||
|
|
1c9d11de23 | ||
|
|
860d7b8446 | ||
|
|
5613e48141 | ||
|
|
3a251e2a38 | ||
|
|
c7c191c01e | ||
|
|
e0bc9d11f1 | ||
|
|
6087bc755a | ||
|
|
8952cff24d | ||
|
|
1c3de94c42 | ||
|
|
9bd3a66b16 | ||
|
|
314d229ccf | ||
|
|
5c2937b05c | ||
|
|
d1a31a9a2b | ||
|
|
5acf4e1a2e | ||
|
|
2b40952429 | ||
|
|
8b306df132 | ||
|
|
8a4fb82b98 | ||
|
|
e0c67b30f8 | ||
|
|
33efc60de7 | ||
|
|
5fc76aaa72 | ||
|
|
24579f67e2 | ||
|
|
d99196aeb1 | ||
|
|
7c531eb411 | ||
|
|
df5303912f | ||
|
|
4479a2b2ee | ||
|
|
05351b7809 | ||
|
|
a3ab3259e3 | ||
|
|
e87d9432c7 | ||
|
|
d0841f792e | ||
|
|
cef3777313 | ||
|
|
0e2d8c1a11 | ||
|
|
c055bd5327 | ||
|
|
3f8c4834a3 | ||
|
|
593549551a | ||
|
|
c0d767351a | ||
|
|
0b9ea25d86 | ||
|
|
fcd0feb61e | ||
|
|
1c4db22c28 | ||
|
|
bdc5b915e8 | ||
|
|
983221a710 | ||
|
|
1cf7ac9260 | ||
|
|
b3a8b1df38 | ||
|
|
cd42566daf | ||
|
|
5d2065b3e7 | ||
|
|
c57a758e91 | ||
|
|
892eea752b | ||
|
|
3f9e76b876 | ||
|
|
29988b5f58 | ||
|
|
951758ef30 | ||
|
|
d8da9af29d | ||
|
|
d774847d00 | ||
|
|
5e38ae1234 | ||
|
|
67b6eafbf0 | ||
|
|
08f7076f6e | ||
|
|
b9a6876d00 | ||
|
|
f76675a561 | ||
|
|
cae1379440 | ||
|
|
a7e34d706d | ||
|
|
2bca3504cd | ||
|
|
bca86191b3 | ||
|
|
0f61521c2d | ||
|
|
37357d4d80 | ||
|
|
38644689c5 | ||
|
|
615d860f82 | ||
|
|
074b2e6ecb | ||
|
|
a71e13ef07 | ||
|
|
b8f11e79c6 | ||
|
|
4f31596e4f | ||
|
|
a1857556ed | ||
|
|
802482fff3 | ||
|
|
371edbf827 | ||
|
|
f8df337893 | ||
|
|
3c8a0d0edb | ||
|
|
7f9d453afe | ||
|
|
69a705731b | ||
|
|
4aa156773c | ||
|
|
61e9d0723c | ||
|
|
2670890845 | ||
|
|
48c9d48789 | ||
|
|
a913369dd0 | ||
|
|
eed5a6f10b | ||
|
|
0634c4bc37 | ||
|
|
8375e3b444 | ||
|
|
790ac76a48 | ||
|
|
1d1ad75afb | ||
|
|
5bd18e4567 | ||
|
|
bda11adfd5 | ||
|
|
000fee96aa | ||
|
|
718cafcd04 | ||
|
|
908dcc0ec8 | ||
|
|
4f6b2bceae | ||
|
|
472b9d1757 | ||
|
|
8a2a608af0 | ||
|
|
60f4a5bc13 | ||
|
|
a5d839fe44 | ||
|
|
9ea64308cb | ||
|
|
b8cbf4e637 | ||
|
|
2808162037 | ||
|
|
9e0d8cae17 | ||
|
|
b6fef04761 | ||
|
|
b1bcf483c9 | ||
|
|
d2e004dc68 | ||
|
|
40361f1b8e | ||
|
|
17eb2f8d91 | ||
|
|
727ea4d473 | ||
|
|
46fa2110da | ||
|
|
ca81f5671a | ||
|
|
bc0eef9ae2 | ||
|
|
093354e231 | ||
|
|
d5f6dbe118 | ||
|
|
41c364002f | ||
|
|
3f34ccc8fb | ||
|
|
05305568ff | ||
|
|
c3766720fa | ||
|
|
c3efcbabb8 | ||
|
|
79b7480f4f | ||
|
|
1a96e594f0 | ||
|
|
32b3ca4159 | ||
|
|
aa2d0eb442 | ||
|
|
65bf3bb6ee | ||
|
|
bfd4efcd94 | ||
|
|
c1704235b4 | ||
|
|
572220ae1f | ||
|
|
48913cbb64 | ||
|
|
86ac0127a5 | ||
|
|
104361608c | ||
|
|
c291358858 | ||
|
|
86d515282e | ||
|
|
67258446f9 | ||
|
|
5c2919074f | ||
|
|
68682ce48a | ||
|
|
81dd95457f | ||
|
|
90e7fd8d74 | ||
|
|
d66cae9c49 | ||
|
|
2323512304 | ||
|
|
213df388f3 | ||
|
|
47747f3256 | ||
|
|
834dfe22dd | ||
|
|
1b190a32bd | ||
|
|
57ebc6344c | ||
|
|
443406f75f | ||
|
|
61ef6dd511 | ||
|
|
e660cbd6ee | ||
|
|
8fa249bab8 | ||
|
|
3524f414ff | ||
|
|
ad7921e32c | ||
|
|
90d0725fe0 | ||
|
|
c784ff1bc3 | ||
|
|
d5277925bc | ||
|
|
5b86b57771 | ||
|
|
c2483cbe4e | ||
|
|
9c3010074d | ||
|
|
199c740c17 | ||
|
|
63896485b0 | ||
|
|
01fc27cb49 | ||
|
|
3611edd1a0 | ||
|
|
63b0c8c67d | ||
|
|
32c0f90999 | ||
|
|
82d8a11021 | ||
|
|
2e9ff4c7d7 | ||
|
|
c95e2f450d | ||
|
|
cb13b9dd77 | ||
|
|
7747674b5c | ||
|
|
29e691a4da | ||
|
|
22b08f1a7f | ||
|
|
65ec773066 | ||
|
|
2f905b81ed | ||
|
|
1534ca41f7 | ||
|
|
7bdab0f23b | ||
|
|
82991a7fc2 | ||
|
|
3c5126c740 | ||
|
|
dbb6059558 | ||
|
|
92a35ba77f | ||
|
|
ddd7979a25 | ||
|
|
3fb26f69e5 | ||
|
|
0b9fc290d2 | ||
|
|
e2f6bd0e2e | ||
|
|
a6e47a0b47 | ||
|
|
be0f030ccf | ||
|
|
b46dab3099 | ||
|
|
c97f69517d | ||
|
|
053296de93 | ||
|
|
249f524ad9 | ||
|
|
62d340bcfe | ||
|
|
9287e66cfc | ||
|
|
98e1ac7375 | ||
|
|
f9fc8ba8aa | ||
|
|
2585798ab5 | ||
|
|
1d85260ccd | ||
|
|
e4f81fb62e | ||
|
|
1e582dea0a | ||
|
|
f00f761996 | ||
|
|
390f0016e6 | ||
|
|
3ecd9cb0cf | ||
|
|
9161c54c43 | ||
|
|
b4cf375044 | ||
|
|
b894f8dbb3 | ||
|
|
af88007cc3 | ||
|
|
c1e567afc7 | ||
|
|
1ee1a924ba | ||
|
|
704fa7a1be | ||
|
|
682b71565d | ||
|
|
3f742d9675 | ||
|
|
0e8ce13c07 | ||
|
|
e4a1b50edb | ||
|
|
832bd41f5d | ||
|
|
af5c2360ea | ||
|
|
86e16f58b9 | ||
|
|
13aa5be9b9 | ||
|
|
1e13740bda | ||
|
|
7e738dedc5 | ||
|
|
d809ac9999 | ||
|
|
952be93124 | ||
|
|
096f452cfa | ||
|
|
7b8a02ede8 | ||
|
|
94c73da943 | ||
|
|
03f6d12e50 | ||
|
|
8938aa4621 |
@@ -0,0 +1,42 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: springcloud/pipeline-base
|
||||
user: appuser
|
||||
environment:
|
||||
_JAVA_OPTIONS: "-Xms1024m -Xmx2048m"
|
||||
TERM: dumb
|
||||
branches:
|
||||
ignore:
|
||||
- gh-pages # list of branches to ignore
|
||||
resource_class: large
|
||||
steps:
|
||||
- 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
|
||||
- save_cache:
|
||||
key: sc-netflix-{{ .Branch }}
|
||||
paths:
|
||||
- ~/.m2
|
||||
- run:
|
||||
name: "Running build"
|
||||
command: ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
||||
- run:
|
||||
name: "Aggregate test results"
|
||||
when: always
|
||||
command: |
|
||||
mkdir -p ~/junit/
|
||||
find . -type f -regex ".*/target/.*-reports/.*" -exec cp {} ~/junit/ \;
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
- store_artifacts:
|
||||
path: ~/junit/
|
||||
destination: artifacts
|
||||
- store_test_results:
|
||||
path: ~/junit/
|
||||
destination: testartifacts
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
# Contributing
|
||||
|
||||
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
|
||||
[Contributor License Agreement](https://cla.pivotal.io/sign/spring).
|
||||
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 [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
|
||||
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
|
||||
[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
|
||||
[Eclipse Code Formatter Plugin](http://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
|
||||
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 [these conventions](http://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
|
||||
message (where XXXX is the issue number).
|
||||
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
Thanks for raising a Spring Cloud issue. What sort of issue are you raising?
|
||||
|
||||
Question
|
||||
|
||||
Please ask questions about how to use something, or to understand why something isn't
|
||||
working as you expect it to, on Stack Overflow using the spring-cloud tag.
|
||||
|
||||
Bug report
|
||||
|
||||
Please provide details of the problem, including the version of Spring Cloud that you
|
||||
are using. 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.
|
||||
|
||||
Enhancement
|
||||
|
||||
Please start by describing the problem that you are trying to solve. There may already
|
||||
be a solution, or there may be a way to solve it that you hadn't considered.
|
||||
-->
|
||||
@@ -7,7 +7,14 @@
|
||||
.settings/
|
||||
.springBeans
|
||||
target/
|
||||
bin/
|
||||
_site/
|
||||
.idea
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.factorypath
|
||||
*.log
|
||||
.shelf
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
|
||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
services:
|
||||
- rabbitmq
|
||||
before_install:
|
||||
- git config user.name "$GIT_NAME"
|
||||
- git config user.email "$GIT_EMAIL"
|
||||
- git config credential.helper "store --file=.git/credentials"
|
||||
- echo "https://$GH_TOKEN:@github.com" > .git/credentials
|
||||
- gem install asciidoctor
|
||||
install:
|
||||
- ./mvnw install -P docs -q -U -DskipTests=true -Dmaven.test.redirectTestOutputToFile=true
|
||||
- ./docs/src/main/asciidoc/ghpages.sh
|
||||
env:
|
||||
global:
|
||||
- GIT_NAME="Dave Syer"
|
||||
- GIT_EMAIL=dsyer@pivotal.io
|
||||
- CI_DEPLOY_USERNAME=buildmaster
|
||||
- secure: aeLXRC5oFSddwnZt1/7G2/OHr7jDbxz0ET7sej3I+eSbe3N5vbzQ6FC08es4l89l54ciXd90I1g2BMw7DTYKOO373FP78XPdAEbifJTU4DGd6fCELmoTtUPhjunBIk7E49hisPbv82892IYYA7qi/hzG548cPyZ1IgiJjq0NCsc=
|
||||
script: |
|
||||
echo "Current Branch: ${TRAVIS_BRANCH}"
|
||||
echo "Pull Request: ${TRAVIS_PULL_REQUEST}"
|
||||
if [ "${TRAVIS_BRANCH}" = master ] && [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
|
||||
echo "[Publishing] Pushing snapshot to Sonatype"
|
||||
./mvnw -s .settings.xml deploy -P release -nsu -Dmaven.test.redirectTestOutputToFile=true
|
||||
else
|
||||
echo "[Installing] Intalling snapshot to local maven repo"
|
||||
./mvnw install -nsu -Dmaven.test.redirectTestOutputToFile=true
|
||||
fi
|
||||
+23
-52
@@ -1,6 +1,9 @@
|
||||
// Do not edit this file (e.g. go instead to docs/src/main/asciidoc)
|
||||
// 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"]
|
||||
|
||||
image::https://travis-ci.org/spring-cloud/spring-cloud-netflix.svg?branch=master[Build Status, link=https://travis-ci.org/spring-cloud/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
|
||||
@@ -16,7 +19,6 @@ Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).
|
||||
* 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
|
||||
* Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations
|
||||
* 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
|
||||
@@ -82,25 +84,22 @@ a modified file in the correct place. Just commit it and push the change.
|
||||
If you don't have an IDE preference we would recommend that you use
|
||||
http://www.springsource.com/developer/sts[Spring Tools Suite] or
|
||||
http://eclipse.org[Eclipse] when working with the code. We use the
|
||||
http://eclipse.org/m2e/[m2eclipe] eclipse plugin for maven support. Other IDEs and tools
|
||||
should also work without issue.
|
||||
http://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 http://eclipse.org/m2e/[m2eclipe] eclipse plugin when working with
|
||||
We recommend the http://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".
|
||||
|
||||
Unfortunately m2e does not yet support Maven 3.3, so once the projects
|
||||
are imported into Eclipse you will also need to tell m2eclipse to use
|
||||
the `.settings.xml` file for the projects. If you do not do this you
|
||||
may see many different errors related to the POMs in the
|
||||
projects. Open your Eclipse preferences, expand the Maven
|
||||
preferences, and select User Settings. In the User Settings field
|
||||
click Browse and navigate to the Spring Cloud project you imported
|
||||
selecting the `.settings.xml` file in that project. Click Apply and
|
||||
then OK to save the preference changes.
|
||||
|
||||
NOTE: Alternatively you can copy the repository settings from https://github.com/spring-cloud/spring-cloud-build/blob/master/.settings.xml[`.settings.xml`] into your own `~/.m2/settings.xml`.
|
||||
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
|
||||
@@ -114,39 +113,6 @@ following command:
|
||||
The generated eclipse projects can be imported by selecting `import existing projects`
|
||||
from the `file` menu.
|
||||
|
||||
==== Adding Project Lombok Agent
|
||||
|
||||
Spring Cloud uses http://projectlombok.org/features/index.html[Project Lombok]
|
||||
to generate getters and setters etc. Compiling from the command line this
|
||||
shouldn't cause any problems, but in an IDE you need to add an agent
|
||||
to the JVM. Full instructions can be found in the Lombok website. The
|
||||
sign that you need to do this is a lot of compiler errors to do with
|
||||
missing methods and fields, e.g.
|
||||
|
||||
[indent=0]
|
||||
----
|
||||
The method getInitialStatus() is undefined for the type EurekaInstanceConfigBean EurekaDiscoveryClientConfiguration.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka line 120 Java Problem
|
||||
The method getInitialStatus() is undefined for the type EurekaInstanceConfigBean EurekaDiscoveryClientConfiguration.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka line 121 Java Problem
|
||||
The method setNonSecurePort(int) is undefined for the type EurekaInstanceConfigBean EurekaDiscoveryClientConfiguration.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka line 112 Java Problem
|
||||
The type EurekaInstanceConfigBean.IdentifyingDataCenterInfo must implement the inherited abstract method DataCenterInfo.getName() EurekaInstanceConfigBean.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka line 131 Java Problem
|
||||
The method getId() is undefined for the type ProxyRouteLocator.ProxyRouteSpec PreDecorationFilter.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre line 60 Java Problem
|
||||
The method getLocation() is undefined for the type ProxyRouteLocator.ProxyRouteSpec PreDecorationFilter.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre line 55 Java Problem
|
||||
----
|
||||
|
||||
==== Importing into Intellij
|
||||
Spring Cloud projects use annotation processing, particularly Lombok, which requires configuration
|
||||
or you will encounter compile problems. It also needs a specific version of maven and a profile
|
||||
enabled. Intellij 14.1+ requires some configuration to ensure these are setup properly.
|
||||
|
||||
1. Click Preferences, Plugins. *Ensure Lombok is installed*
|
||||
2. Click New, Project from Existing Sources, choose your spring-cloud-sleuth directory
|
||||
3. Choose Maven, and select Environment Settings. *Ensure you are using Maven 3.3.3*
|
||||
4. In the next screen, *Select the profile `spring`* click Next until Finish.
|
||||
5. Click Preferences, "Build, Execution, Deployment", Compiler, Annotation Processors. *Click Enable Annotation Processing*
|
||||
6. Click Build, Rebuild Project, and you are ready to go!
|
||||
|
||||
==== Importing into other IDEs
|
||||
Maven is well supported by most Java IDEs. Refer to you vendor documentation.
|
||||
|
||||
|
||||
== Contributing
|
||||
@@ -159,12 +125,17 @@ 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://support.springsource.com/spring_committer_signup[contributor's agreement].
|
||||
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.
|
||||
@@ -172,7 +143,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
|
||||
https://github.com/spring-cloud/spring-cloud-build/blob/master/spring-cloud-build/eclipse-code-formatter.xml[Spring
|
||||
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
|
||||
http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
|
||||
Plugin] to import the same file.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
releaser:
|
||||
maven:
|
||||
buildCommand: ./scripts/build.sh {{systemProps}}
|
||||
@@ -0,0 +1,297 @@
|
||||
// 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
|
||||
http://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
|
||||
http://www.springsource.com/developer/sts[Spring Tools Suite] or
|
||||
http://eclipse.org[Eclipse] when working with the code. We use the
|
||||
http://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 http://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
|
||||
http://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 http://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"
|
||||
"http://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.
|
||||
+19
-13
@@ -1,30 +1,28 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>1.1.0.M4</version>
|
||||
<relativePath />
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>2.0.3.RELEASE</version>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix-docs</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Netflix Docs</name>
|
||||
<version>1.1.0.M4</version>
|
||||
<description>Spring Cloud Docs</description>
|
||||
<properties>
|
||||
<docs.main>spring-cloud-netflix</docs.main>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
<docs.whitelisted.branches>1.2.x,1.3.x,1.4.x</docs.whitelisted.branches>
|
||||
</properties>
|
||||
<build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
@@ -32,11 +30,19 @@
|
||||
<id>docs</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-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>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
image::https://travis-ci.org/spring-cloud/spring-cloud-netflix.svg?branch=master[Build Status, link=https://travis-ci.org/spring-cloud/spring-cloud-netflix]
|
||||
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::intro.adoc[]
|
||||
|
||||
@@ -8,7 +11,6 @@ include::intro.adoc[]
|
||||
* 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
|
||||
* Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations
|
||||
* 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
|
||||
|
||||
@@ -1,54 +1,330 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'`
|
||||
set -e
|
||||
|
||||
if ! (git remote set-branches --add origin gh-pages && git fetch -q); then
|
||||
echo "No gh-pages, so not syncing"
|
||||
exit 0
|
||||
fi
|
||||
# Set default props like MAVEN_PATH, ROOT_FOLDER etc.
|
||||
function set_default_props() {
|
||||
# The script should be executed from the root folder
|
||||
ROOT_FOLDER=`pwd`
|
||||
echo "Current folder is ${ROOT_FOLDER}"
|
||||
|
||||
if ! [ -d docs/target/generated-docs ]; then
|
||||
echo "No gh-pages sources in docs/target/generated-docs, so not syncing"
|
||||
exit 0
|
||||
fi
|
||||
if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then
|
||||
echo "You're not in the root folder of the project!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find name of current branch
|
||||
###################################################################
|
||||
branch=$TRAVIS_BRANCH
|
||||
[ "$branch" == "" ] && branch=`git rev-parse --abbrev-ref HEAD`
|
||||
target=.
|
||||
if [ "$branch" != "master" ]; then target=./$branch; mkdir -p $target; fi
|
||||
# Prop that will let commit the changes
|
||||
COMMIT_CHANGES="no"
|
||||
MAVEN_PATH=${MAVEN_PATH:-}
|
||||
echo "Path to Maven is [${MAVEN_PATH}]"
|
||||
REPO_NAME=${PWD##*/}
|
||||
echo "Repo name is [${REPO_NAME}]"
|
||||
SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git}
|
||||
echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}"
|
||||
}
|
||||
|
||||
# Check if gh-pages exists and docs have been built
|
||||
function check_if_anything_to_sync() {
|
||||
git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'`
|
||||
|
||||
if ! (git remote set-branches --add origin gh-pages && git fetch -q); then
|
||||
echo "No gh-pages, so not syncing"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then
|
||||
echo "No gh-pages sources in docs/target/generated-docs, so not syncing"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
function retrieve_current_branch() {
|
||||
# Code getting the name of the current branch. For master we want to publish as we did until now
|
||||
# http://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}
|
||||
if [[ -z "${CURRENT_BRANCH}" ]] ; then
|
||||
CURRENT_BRANCH=$(git symbolic-ref -q HEAD)
|
||||
CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/}
|
||||
CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD}
|
||||
fi
|
||||
echo "Current branch is [${CURRENT_BRANCH}]"
|
||||
git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script"
|
||||
}
|
||||
|
||||
# Switches to the provided value of the release version. We always prefix it with `v`
|
||||
function switch_to_tag() {
|
||||
git checkout v${VERSION}
|
||||
}
|
||||
|
||||
# Build the docs if switch is on
|
||||
function build_docs_if_applicable() {
|
||||
if [[ "${BUILD}" == "yes" ]] ; then
|
||||
./mvnw clean install -P docs -pl docs -DskipTests
|
||||
fi
|
||||
}
|
||||
|
||||
# Get the name of the `docs.main` property
|
||||
# Get whitelisted 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" \
|
||||
-Dexec.args='${docs.main}' \
|
||||
--non-recursive \
|
||||
org.codehaus.mojo:exec-maven-plugin:1.3.1:exec)
|
||||
echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]"
|
||||
|
||||
|
||||
WHITELIST_PROPERTY=${WHITELIST_PROPERTY:-"docs.whitelisted.branches"}
|
||||
WHITELISTED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \
|
||||
-Dexec.executable="echo" \
|
||||
-Dexec.args="\${${WHITELIST_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}]"
|
||||
}
|
||||
|
||||
# Stash any outstanding changes
|
||||
###################################################################
|
||||
git diff-index --quiet HEAD
|
||||
dirty=$?
|
||||
if [ "$dirty" != "0" ]; then git stash; fi
|
||||
function stash_changes() {
|
||||
git diff-index --quiet HEAD && dirty=$? || (echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1")
|
||||
if [ "$dirty" != "0" ]; then git stash; fi
|
||||
}
|
||||
|
||||
# Switch to gh-pages branch to sync it with current branch
|
||||
###################################################################
|
||||
git checkout gh-pages
|
||||
|
||||
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
|
||||
# Not ignored...
|
||||
cp -rf $f $target
|
||||
git add -A $target/$file
|
||||
function add_docs_from_target() {
|
||||
local DESTINATION_REPO_FOLDER
|
||||
if [[ -z "${DESTINATION}" && -z "${CLONE}" ]] ; then
|
||||
DESTINATION_REPO_FOLDER=${ROOT_FOLDER}
|
||||
elif [[ "${CLONE}" == "yes" ]]; then
|
||||
mkdir -p ${ROOT_FOLDER}/target
|
||||
local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static
|
||||
if [[ ! -e "${clonedStatic}/.git" ]]; then
|
||||
echo "Cloning Spring Cloud Static to target"
|
||||
git clone ${SPRING_CLOUD_STATIC_REPO} ${clonedStatic} && git checkout gh-pages
|
||||
else
|
||||
echo "Spring Cloud Static already cloned - will pull changes"
|
||||
cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages
|
||||
fi
|
||||
DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME}
|
||||
mkdir -p ${DESTINATION_REPO_FOLDER}
|
||||
else
|
||||
if [[ ! -e "${DESTINATION}/.git" ]]; then
|
||||
echo "[${DESTINATION}] is not a git repository"
|
||||
exit 1
|
||||
fi
|
||||
DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME}
|
||||
mkdir -p ${DESTINATION_REPO_FOLDER}
|
||||
echo "Destination was provided [${DESTINATION}]"
|
||||
fi
|
||||
cd ${DESTINATION_REPO_FOLDER}
|
||||
git checkout gh-pages
|
||||
git pull origin gh-pages
|
||||
|
||||
# Add git branches
|
||||
###################################################################
|
||||
if [[ -z "${VERSION}" ]] ; then
|
||||
copy_docs_for_current_version
|
||||
else
|
||||
copy_docs_for_provided_version
|
||||
fi
|
||||
commit_changes_if_applicable
|
||||
}
|
||||
|
||||
|
||||
# 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"
|
||||
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
|
||||
# Not ignored...
|
||||
cp -rf $f ${ROOT_FOLDER}/
|
||||
git add -A ${ROOT_FOLDER}/$file
|
||||
fi
|
||||
done
|
||||
COMMIT_CHANGES="yes"
|
||||
else
|
||||
echo -e "Current branch is [${CURRENT_BRANCH}]"
|
||||
# http://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
|
||||
mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH}
|
||||
echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! 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
|
||||
# Not ignored...
|
||||
# We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html
|
||||
if [[ "${file}" == "${MAIN_ADOC_VALUE}.html" ]] ; then
|
||||
# We don't want to copy the spring-cloud-sleuth.html
|
||||
# we want it to be converted to index.html
|
||||
cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html
|
||||
git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html
|
||||
else
|
||||
cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}
|
||||
git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file
|
||||
fi
|
||||
fi
|
||||
done
|
||||
COMMIT_CHANGES="yes"
|
||||
else
|
||||
echo -e "Branch [${CURRENT_BRANCH}] is not on the white list! Check out the Maven [${WHITELIST_PROPERTY}] property in
|
||||
[docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Copies the docs by using the explicitly provided version
|
||||
function copy_docs_for_provided_version() {
|
||||
local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION}
|
||||
mkdir -p ${FOLDER}
|
||||
echo -e "Current tag is [v${VERSION}] Will copy the current docs to the [${FOLDER}] folder"
|
||||
for f in ${ROOT_FOLDER}/docs/target/generated-docs/*; do
|
||||
file=${f#${ROOT_FOLDER}/docs/target/generated-docs/*}
|
||||
copy_docs_for_branch ${file} ${FOLDER}
|
||||
done
|
||||
COMMIT_CHANGES="yes"
|
||||
CURRENT_BRANCH="v${VERSION}"
|
||||
}
|
||||
|
||||
# Copies the docs from target to the provided destination
|
||||
# Params:
|
||||
# $1 - file from target
|
||||
# $2 - destination to which copy the files
|
||||
function copy_docs_for_branch() {
|
||||
local file=$1
|
||||
local destination=$2
|
||||
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^${file}$; then
|
||||
# Not ignored...
|
||||
# We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html
|
||||
if [[ ("${file}" == "${MAIN_ADOC_VALUE}.html") || ("${file}" == "${REPO_NAME}.html") ]] ; then
|
||||
# We don't want to copy the spring-cloud-sleuth.html
|
||||
# we want it to be converted to index.html
|
||||
cp -rf $f ${destination}/index.html
|
||||
git add -A ${destination}/index.html
|
||||
else
|
||||
cp -rf $f ${destination}
|
||||
git add -A ${destination}/$file
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function commit_changes_if_applicable() {
|
||||
if [[ "${COMMIT_CHANGES}" == "yes" ]] ; then
|
||||
COMMIT_SUCCESSFUL="no"
|
||||
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.
|
||||
# This is a little extreme. Use with care!
|
||||
###################################################################
|
||||
if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then
|
||||
git push origin gh-pages
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Switch back to the previous branch and exit block
|
||||
function checkout_previous_branch() {
|
||||
# If -version was provided we need to come back to root project
|
||||
cd ${ROOT_FOLDER}
|
||||
git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script"
|
||||
if [ "$dirty" != "0" ]; then git stash pop; fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Assert if properties have been properly passed
|
||||
function assert_properties() {
|
||||
echo "VERSION [${VERSION}], DESTINATION [${DESTINATION}], CLONE [${CLONE}]"
|
||||
if [[ "${VERSION}" != "" && (-z "${DESTINATION}" && -z "${CLONE}") ]] ; then echo "Version was set but destination / clone was not!"; exit 1;fi
|
||||
if [[ ("${DESTINATION}" != "" && "${CLONE}" != "") && -z "${VERSION}" ]] ; then echo "Destination / clone was set but version was not!"; exit 1;fi
|
||||
if [[ "${DESTINATION}" != "" && "${CLONE}" == "yes" ]] ; then echo "Destination and clone was set. Pick one!"; exit 1;fi
|
||||
}
|
||||
|
||||
# Prints the usage
|
||||
function print_usage() {
|
||||
cat <<EOF
|
||||
The idea of this script is to update gh-pages branch with the generated docs. Without any options
|
||||
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
|
||||
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
|
||||
- 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
|
||||
switch to gh-pages of that repo and copy the generated docs to `docs/<project-name>/<version>`
|
||||
|
||||
USAGE:
|
||||
|
||||
You can use the following options:
|
||||
|
||||
-v|--version - the script will apply the whole procedure for a particular library version
|
||||
-d|--destination - the root of destination folder where the docs should be copied. You have to use the full path.
|
||||
E.g. point to spring-cloud-static folder. Can't be used with (-c)
|
||||
-b|--build - will run the standard build process after checking out the branch
|
||||
-c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination.
|
||||
Obviously can't be used with (-d)
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
# ==========================================
|
||||
# ____ ____ _____ _____ _____ _______
|
||||
# / ____|/ ____| __ \|_ _| __ \__ __|
|
||||
# | (___ | | | |__) | | | | |__) | | |
|
||||
# \___ \| | | _ / | | | ___/ | |
|
||||
# ____) | |____| | \ \ _| |_| | | |
|
||||
# |_____/ \_____|_| \_\_____|_| |_|
|
||||
#
|
||||
# ==========================================
|
||||
|
||||
while [[ $# > 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
case ${key} in
|
||||
-v|--version)
|
||||
VERSION="$2"
|
||||
shift # past argument
|
||||
;;
|
||||
-d|--destination)
|
||||
DESTINATION="$2"
|
||||
shift # past argument
|
||||
;;
|
||||
-b|--build)
|
||||
BUILD="yes"
|
||||
;;
|
||||
-c|--clone)
|
||||
CLONE="yes"
|
||||
;;
|
||||
-h|--help)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option: [$1]"
|
||||
print_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift # past argument or value
|
||||
done
|
||||
|
||||
git add -A README.adoc || echo "No change to README.adoc"
|
||||
git commit -a -m "Sync docs from $branch to gh-pages" || echo "Nothing committed"
|
||||
|
||||
# Uncomment the following push if you want to auto push to
|
||||
# the gh-pages branch whenever you commit to branch locally.
|
||||
# This is a little extreme. Use with care!
|
||||
###################################################################
|
||||
git push origin gh-pages || echo "Cannot push gh-pages"
|
||||
|
||||
# Finally, switch back to the current branch and exit block
|
||||
git checkout $branch
|
||||
if [ "$dirty" != "0" ]; then git stash pop; fi
|
||||
|
||||
exit 0
|
||||
assert_properties
|
||||
set_default_props
|
||||
check_if_anything_to_sync
|
||||
if [[ -z "${VERSION}" ]] ; then
|
||||
retrieve_current_branch
|
||||
else
|
||||
switch_to_tag
|
||||
fi
|
||||
build_docs_if_applicable
|
||||
retrieve_doc_properties
|
||||
stash_changes
|
||||
add_docs_from_target
|
||||
checkout_previous_branch
|
||||
Regular → Executable
+1418
-859
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
base_dir = File.join(File.dirname(__FILE__),'../../..')
|
||||
src_dir = File.join(base_dir, "/src/main/asciidoc")
|
||||
require 'asciidoctor'
|
||||
require 'optparse'
|
||||
|
||||
options = {}
|
||||
file = "#{src_dir}/README.adoc"
|
||||
|
||||
OptionParser.new do |o|
|
||||
o.on('-o OUTPUT_FILE', 'Output file (default is stdout)') { |file| options[:to_file] = file unless file=='-' }
|
||||
o.on('-h', '--help') { puts o; exit }
|
||||
o.parse!
|
||||
end
|
||||
|
||||
file = ARGV[0] if ARGV.length>0
|
||||
|
||||
srcDir = File.dirname(file)
|
||||
out = "// Do not edit this file (e.g. go instead to docs/src/main/asciidoc)\n\n"
|
||||
doc = Asciidoctor.load_file file, safe: :safe, parse: false, attributes: 'allow-uri-read'
|
||||
out << doc.reader.read
|
||||
|
||||
unless options[:to_file]
|
||||
puts out
|
||||
else
|
||||
File.open(options[:to_file],'w+') do |file|
|
||||
file.write(out)
|
||||
end
|
||||
end
|
||||
+313
-293
@@ -1,295 +1,315 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="12">
|
||||
<profile kind="CodeFormatterProfile" name="Spring Cloud Java Conventions" version="12">
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="90"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="90"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
</profile>
|
||||
<profiles version="13">
|
||||
<profile kind="CodeFormatterProfile" name="Spring Cloud Java Conventions" version="12">
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="90"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.source" value="9"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="9"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="9"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="90"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
@@ -10,9 +10,10 @@ org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
@@ -51,11 +52,11 @@ org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=default
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
|
||||
@@ -102,7 +103,9 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
org.eclipse.jdt.core.compiler.processAnnotations=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
@@ -113,11 +116,14 @@ org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_e
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
@@ -127,6 +133,8 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
@@ -153,6 +161,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
@@ -184,7 +193,8 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=8
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
@@ -212,7 +222,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
@@ -379,11 +389,24 @@ org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=false
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=true
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -57,27 +57,27 @@ case "`uname`" in
|
||||
#
|
||||
# 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
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
|
||||
#
|
||||
@@ -219,16 +219,35 @@ concat_lines() {
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
echo "Running version check"
|
||||
VERSION=$( sed '\!<parent!,\!</parent!d' `dirname $0`/pom.xml | grep '<version' | head -1 | sed -e 's/.*<version>//' -e 's!</version>.*$!!' )
|
||||
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"
|
||||
else
|
||||
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | 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"
|
||||
else
|
||||
echo Deactivating \"central\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | 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} "$@"
|
||||
|
||||
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
|
||||
@@ -1,145 +1,145 @@
|
||||
@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 http://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"
|
||||
@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 http://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%
|
||||
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%
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>1.1.0.M4</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.1.0.M4</version>
|
||||
<version>2.0.3.RELEASE</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.RELEASE</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<scm>
|
||||
<url>https://github.com/spring-cloud/spring-cloud-netflix</url>
|
||||
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-netflix.git</connection>
|
||||
@@ -21,48 +21,49 @@
|
||||
</scm>
|
||||
<properties>
|
||||
<bintray.package>netflix</bintray.package>
|
||||
<spring-cloud-commons.version>1.1.0.M4</spring-cloud-commons.version>
|
||||
<spring-cloud-config.version>1.1.0.M4</spring-cloud-config.version>
|
||||
<spring-cloud-stream.version>1.0.0.M3</spring-cloud-stream.version>
|
||||
<main.basedir>${basedir}</main.basedir>
|
||||
<archaius.version>0.6.5</archaius.version>
|
||||
<eureka.version>1.3.4</eureka.version>
|
||||
<feign.version>8.12.1</feign.version>
|
||||
<hystrix.version>1.4.21</hystrix.version>
|
||||
<ribbon.version>2.1.0</ribbon.version>
|
||||
<servo.version>0.10.0</servo.version>
|
||||
<zuul.version>1.1.0</zuul.version>
|
||||
<rxjava.version>1.0.14</rxjava.version>
|
||||
<java.version>1.7</java.version>
|
||||
<turbine.version>1.0.0</turbine.version>
|
||||
<spring-integration-dsl.version>1.0.0.RELEASE</spring-integration-dsl.version>
|
||||
<cloud-connectors.version>1.1.1.RELEASE</cloud-connectors.version>
|
||||
<eureka-jersey.version>1.19</eureka-jersey.version>
|
||||
<jackson.version>2.7.3</jackson.version>
|
||||
<spring-cloud-commons.version>2.0.3.RELEASE</spring-cloud-commons.version>
|
||||
<spring-cloud-config.version>2.0.3.RELEASE</spring-cloud-config.version>
|
||||
<spring-cloud-stream.version>Elmhurst.SR2</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>
|
||||
|
||||
<!-- 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>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<version>${maven-eclipse-plugin.version}</version>
|
||||
<configuration>
|
||||
<useProjectReferences>false</useProjectReferences>
|
||||
<additionalConfig>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.ui.prefs</name>
|
||||
<location>${main.basedir}/eclipse/org.eclipse.jdt.ui.prefs</location>
|
||||
<location>${maven.multiModuleProjectDirectory}/eclipse/org.eclipse.jdt.ui.prefs</location>
|
||||
</file>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.core.prefs</name>
|
||||
<location>${main.basedir}/eclipse/org.eclipse.jdt.core.prefs</location>
|
||||
<location>${maven.multiModuleProjectDirectory}/eclipse/org.eclipse.jdt.core.prefs</location>
|
||||
</file>
|
||||
</additionalConfig>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
@@ -71,457 +72,94 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons-parent</artifactId>
|
||||
<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>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons-dependencies</artifactId>
|
||||
<version>${spring-cloud-commons.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config</artifactId>
|
||||
<artifactId>spring-cloud-test-support</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>${spring-cloud-commons.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-dependencies</artifactId>
|
||||
<version>${spring-cloud-config.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-atlas</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-eureka</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-eureka-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-feign</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-hystrix</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-ribbon</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-spectator</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-turbine</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-turbine-stream</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-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-spectator</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-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<artifactId>spring-cloud-stream-dependencies</artifactId>
|
||||
<version>${spring-cloud-stream.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.netflix-commons</groupId>
|
||||
<artifactId>netflix-commons-util</artifactId>
|
||||
<version>0.1.1</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>
|
||||
<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>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax-inject</groupId>
|
||||
<artifactId>javax-inject</artifactId>
|
||||
<version>1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-core</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>log4j</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>com.netflix.blitz4j</artifactId>
|
||||
<groupId>blitz4j</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Eureka core dep that is now optional -->
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-httpclient</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-hystrix</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-okhttp</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</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>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>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-java-dsl</artifactId>
|
||||
<version>${spring-integration-dsl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>2.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>d3js</artifactId>
|
||||
<version>3.4.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>jquery</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>bootstrap</artifactId>
|
||||
<version>3.2.0</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 -->
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<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-amqp</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-spectator</module>
|
||||
<module>spring-cloud-netflix-turbine</module>
|
||||
<module>spring-cloud-netflix-turbine-stream</module>
|
||||
<module>spring-cloud-netflix-sidecar</module>
|
||||
<module>spring-cloud-starter-atlas</module>
|
||||
<module>spring-cloud-starter-eureka</module>
|
||||
<module>spring-cloud-starter-eureka-server</module>
|
||||
<module>spring-cloud-starter-feign</module>
|
||||
<module>spring-cloud-starter-hystrix</module>
|
||||
<module>spring-cloud-starter-hystrix-dashboard</module>
|
||||
<module>spring-cloud-starter-ribbon</module>
|
||||
<module>spring-cloud-starter-spectator</module>
|
||||
<module>spring-cloud-starter-turbine</module>
|
||||
<module>spring-cloud-starter-turbine-amqp</module>
|
||||
<module>spring-cloud-starter-turbine-stream</module>
|
||||
<module>spring-cloud-starter-zuul</module>
|
||||
<module>spring-cloud-netflix-zuul</module>
|
||||
<module>spring-cloud-netflix-ribbon</module>
|
||||
<module>spring-cloud-starter-netflix</module>
|
||||
<module>docs</module>
|
||||
</modules>
|
||||
</modules>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>spring</id>
|
||||
@@ -529,15 +167,18 @@
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>http://repo.spring.io/libs-snapshot-local</url>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>http://repo.spring.io/libs-milestone-local</url>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
@@ -545,7 +186,7 @@
|
||||
<repository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>http://repo.spring.io/release</url>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
@@ -555,20 +196,73 @@
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>http://repo.spring.io/libs-snapshot-local</url>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>http://repo.spring.io/libs-milestone-local</url>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/libs-release-local</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>sonar</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-unit-test</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<propertyName>surefireArgLine</propertyName>
|
||||
<destFile>${project.build.directory}/jacoco.exec</destFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>post-unit-test</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- Sets the path to the file which contains the execution data. -->
|
||||
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- Sets the VM argument line used when unit tests are run. -->
|
||||
<argLine>${surefireArgLine}</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
(cd spring-cloud-netflix-hystrix-contract && ../mvnw clean install -B -Pdocs ${@})
|
||||
./mvnw clean install -B -Pdocs ${@}
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
(cd spring-cloud-netflix-hystrix-contract && ../mvnw clean install -B -Pdocs -DskipTests)
|
||||
./mvnw clean install -B -Pdocs -DskipTests -fae
|
||||
@@ -4,16 +4,19 @@ set -o errexit
|
||||
|
||||
mkdir -p target
|
||||
|
||||
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/brewery/master/acceptance-tests/scripts/runDockerAcceptanceTests.sh"
|
||||
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/brewery/master/runAcceptanceTests.sh"
|
||||
AT_WHAT_TO_TEST="EUREKA"
|
||||
|
||||
cd target
|
||||
|
||||
curl "${SCRIPT_URL}" --output runDockerAcceptanceTests.sh
|
||||
curl "${SCRIPT_URL}" --output runAcceptanceTests.sh
|
||||
|
||||
chmod +x runDockerAcceptanceTests.sh
|
||||
chmod +x runAcceptanceTests.sh
|
||||
|
||||
./runDockerAcceptanceTests.sh -t "${AT_WHAT_TO_TEST}"
|
||||
echo "Killing all running apps"
|
||||
./runAcceptanceTests.sh -t "${AT_WHAT_TO_TEST}" --killnow
|
||||
|
||||
./runAcceptanceTests.sh -t "${AT_WHAT_TO_TEST}" --killattheend
|
||||
|
||||
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/tests/master/scripts/runTests.sh"
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?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 http://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.3.RELEASE</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>
|
||||
+53
-32
@@ -16,35 +16,34 @@
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
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;
|
||||
|
||||
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 lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
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.endpoint.Endpoint;
|
||||
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;
|
||||
@@ -53,46 +52,66 @@ 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 })
|
||||
@CommonsLog
|
||||
@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
|
||||
private List<AbstractConfiguration> externalConfigurations;
|
||||
@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 ConfigurableEnvironmentConfiguration configurableEnvironmentConfiguration() {
|
||||
ConfigurableEnvironmentConfiguration envConfig = new ConfigurableEnvironmentConfiguration(
|
||||
this.env);
|
||||
configureArchaius(envConfig);
|
||||
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(Endpoint.class)
|
||||
@ConditionalOnClass(Health.class)
|
||||
protected static class ArchaiusEndpointConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnEnabledEndpoint
|
||||
protected ArchaiusEndpoint archaiusEndpoint() {
|
||||
return new ArchaiusEndpoint();
|
||||
}
|
||||
@@ -101,8 +120,8 @@ public class ArchaiusAutoConfiguration {
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", matchIfMissing = true)
|
||||
@ConditionalOnClass(EnvironmentChangeEvent.class)
|
||||
protected static class PropagateEventsConfiguration implements
|
||||
ApplicationListener<EnvironmentChangeEvent> {
|
||||
protected static class PropagateEventsConfiguration
|
||||
implements ApplicationListener<EnvironmentChangeEvent> {
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
@@ -110,11 +129,12 @@ public class ArchaiusAutoConfiguration {
|
||||
public void onApplicationEvent(EnvironmentChangeEvent event) {
|
||||
AbstractConfiguration manager = ConfigurationManager.getConfigInstance();
|
||||
for (String key : event.getKeys()) {
|
||||
for (ConfigurationListener listener : manager.getConfigurationListeners()) {
|
||||
for (ConfigurationListener listener : manager
|
||||
.getConfigurationListeners()) {
|
||||
Object source = event.getSource();
|
||||
// TODO: Handle add vs set vs delete?
|
||||
int type = AbstractConfiguration.EVENT_SET_PROPERTY;
|
||||
String value = env.getProperty(key);
|
||||
String value = this.env.getProperty(key);
|
||||
boolean beforeUpdate = false;
|
||||
listener.configurationChanged(new ConfigurationEvent(source, type,
|
||||
key, value, beforeUpdate));
|
||||
@@ -123,9 +143,9 @@ public class ArchaiusAutoConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) {
|
||||
protected static void configureArchaius(ConfigurableEnvironmentConfiguration envConfig, ConfigurableEnvironment env, List<AbstractConfiguration> externalConfigurations) {
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
String appName = this.env.getProperty("spring.application.name");
|
||||
String appName = env.getProperty("spring.application.name");
|
||||
if (appName == null) {
|
||||
appName = "application";
|
||||
log.warn("No spring.application.name found, defaulting to 'application'");
|
||||
@@ -144,8 +164,7 @@ public class ArchaiusAutoConfiguration {
|
||||
config.addConfiguration(envConfig,
|
||||
ConfigurableEnvironmentConfiguration.class.getSimpleName());
|
||||
|
||||
// below come from ConfigurationManager.createDefaultConfigInstance()
|
||||
DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration();
|
||||
defaultURLConfig = new DynamicURLConfiguration();
|
||||
try {
|
||||
config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
|
||||
}
|
||||
@@ -165,18 +184,19 @@ public class ArchaiusAutoConfiguration {
|
||||
|
||||
ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
|
||||
config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES);
|
||||
config.setContainerConfigurationIndex(config
|
||||
.getIndexOfConfiguration(appOverrideConfig));
|
||||
config.setContainerConfigurationIndex(
|
||||
config.getIndexOfConfiguration(appOverrideConfig));
|
||||
|
||||
addArchaiusConfiguration(config);
|
||||
}
|
||||
else {
|
||||
// TODO: reinstall ConfigurationManager
|
||||
log.warn("Netflix ConfigurationManager has already been installed, unable to re-install");
|
||||
log.warn(
|
||||
"Netflix ConfigurationManager has already been installed, unable to re-install");
|
||||
}
|
||||
}
|
||||
|
||||
private void addArchaiusConfiguration(ConcurrentCompositeConfiguration config) {
|
||||
private static void addArchaiusConfiguration(ConcurrentCompositeConfiguration config) {
|
||||
if (ConfigurationManager.isConfigurationInstalled()) {
|
||||
AbstractConfiguration installedConfiguration = ConfigurationManager
|
||||
.getConfigInstance();
|
||||
@@ -187,7 +207,8 @@ public class ArchaiusAutoConfiguration {
|
||||
else {
|
||||
installedConfiguration.append(config);
|
||||
if (!(installedConfiguration instanceof AggregatedConfiguration)) {
|
||||
log.warn("Appending a configuration to an existing non-aggregated installed configuration will have no effect");
|
||||
log.warn(
|
||||
"Appending a configuration to an existing non-aggregated installed configuration will have no effect");
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -24,7 +24,8 @@ 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.AbstractEndpoint;
|
||||
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;
|
||||
@@ -32,15 +33,12 @@ import com.netflix.config.ConfigurationManager;
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ArchaiusEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
@Endpoint(id = "archaius")
|
||||
public class ArchaiusEndpoint {
|
||||
|
||||
public ArchaiusEndpoint() {
|
||||
super("archaius");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ReadOperation
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
AbstractConfiguration config = ConfigurationManager.getConfigInstance();
|
||||
if (config instanceof ConcurrentCompositeConfiguration) {
|
||||
ConcurrentCompositeConfiguration composite = (ConcurrentCompositeConfiguration) config;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"properties": [
|
||||
{
|
||||
"defaultValue": "true",
|
||||
"name": "archaius.propagate.environmentChangedEvent",
|
||||
"description": "Propagates EnvironmentChanged events to Archaius ConfigurationManager.",
|
||||
"type": "java.lang.Boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration
|
||||
+6
-6
@@ -23,14 +23,14 @@ 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 org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
@@ -94,9 +94,9 @@ public class ArchaiusAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationWithInjectedDbConfiguration() throws Exception {
|
||||
public void configurationWithInjectedConfiguration() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class, ArchaiusExternalConfiguration.class);
|
||||
ArchaiusAutoConfiguration.class, TestArchaiusExternalConfiguration.class);
|
||||
DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance()
|
||||
.getStringProperty("db.property", null);
|
||||
DynamicStringProperty secondDbProperty = DynamicPropertyFactory.getInstance()
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,17 +5,18 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.1.0.M4</version>
|
||||
<version>2.0.3.RELEASE</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>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
</properties>
|
||||
<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>
|
||||
@@ -23,11 +24,52 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
<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>
|
||||
@@ -39,93 +81,21 @@
|
||||
<artifactId>spring-cloud-context</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-client</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-server</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.servo</groupId>
|
||||
<artifactId>servo-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.netflix-commons</groupId>
|
||||
<artifactId>netflix-commons-util</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
<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>net.java.dev.rome</groupId>
|
||||
<artifactId>rome</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-hystrix</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-okhttp</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>
|
||||
@@ -136,41 +106,16 @@
|
||||
<artifactId>hystrix-javanica</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-eureka</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<optional>true</optional>
|
||||
<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>io.reactivex</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
@@ -182,41 +127,60 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<!-- Only needed at compile time -->
|
||||
<scope>compile</scope>
|
||||
<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-starter-jdbc</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<artifactId>spring-boot-autoconfigure-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-smile</artifactId>
|
||||
<optional>true</optional>
|
||||
<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>
|
||||
|
||||
-104
@@ -1,104 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.config.client.ConfigClientProperties;
|
||||
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.EurekaClient;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
* Bootstrap configuration for a config client that wants to lookup the config server via
|
||||
* discovery.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConditionalOnClass({ EurekaClient.class, ConfigServicePropertySourceLocator.class })
|
||||
@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false)
|
||||
@Configuration
|
||||
@Import(EurekaClientAutoConfiguration.class)
|
||||
@CommonsLog
|
||||
public class DiscoveryClientConfigServiceBootstrapConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ConfigClientProperties config;
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient client;
|
||||
|
||||
@Autowired
|
||||
private EurekaClient eurekaClient;
|
||||
|
||||
@EventListener(ContextRefreshedEvent.class)
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
// TODO: re-instate heart beat (maybe? isn't it handled in the child context?)
|
||||
|
||||
private void refresh() {
|
||||
try {
|
||||
log.debug("Locating configserver via discovery");
|
||||
InstanceInfo server = this.eurekaClient.getNextServerFromEureka(
|
||||
this.config.getDiscovery().getServiceId(), false);
|
||||
String url = getHomePage(server);
|
||||
if (server.getMetadata().containsKey("password")) {
|
||||
String user = server.getMetadata().get("user");
|
||||
user = user == null ? "user" : user;
|
||||
this.config.setUsername(user);
|
||||
String password = server.getMetadata().get("password");
|
||||
this.config.setPassword(password);
|
||||
}
|
||||
if (server.getMetadata().containsKey("configPath")) {
|
||||
String path = server.getMetadata().get("configPath");
|
||||
if (url.endsWith("/") && path.startsWith("/")) {
|
||||
url = url.substring(0, url.length() - 1);
|
||||
}
|
||||
url = url + path;
|
||||
}
|
||||
this.config.setUri(url);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
log.warn("Could not locate configserver via discovery", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String getHomePage(InstanceInfo server) {
|
||||
List<ServiceInstance> instances = this.client
|
||||
.getInstances(this.config.getDiscovery().getServiceId());
|
||||
if (instances == null || instances.isEmpty()) {
|
||||
return server.getHomePageUrl();
|
||||
}
|
||||
return instances.get(0).getUri().toString() + "/";
|
||||
}
|
||||
|
||||
}
|
||||
-100
@@ -1,100 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.endpoint;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.ServletWrappingController;
|
||||
|
||||
public abstract class ServletWrappingEndpoint implements InitializingBean,
|
||||
ApplicationContextAware, ServletContextAware, MvcEndpoint {
|
||||
|
||||
// TODO: move to spring-boot?
|
||||
|
||||
private String path;
|
||||
|
||||
private boolean sensitive;
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
private final ServletWrappingController controller = new ServletWrappingController();
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.controller.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.controller.setServletContext(servletContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.controller.setApplicationContext(applicationContext);
|
||||
}
|
||||
|
||||
protected ServletWrappingEndpoint(Class<?> servletClass, String servletName,
|
||||
String path, boolean sensitive, boolean enabled) {
|
||||
this.controller.setServletClass(servletClass);
|
||||
this.controller.setServletName(servletName);
|
||||
this.path = path;
|
||||
this.sensitive = sensitive;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@RequestMapping("**")
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
return this.controller.handleRequest(request, response);
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public ServletWrappingController getController() {
|
||||
return controller;
|
||||
}
|
||||
@Override
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return this.sensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Endpoint<?>> getEndpointType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
-63
@@ -1,63 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
/**
|
||||
* Subclass of {@link DiscoveryClient} that sends a {@link HeartbeatEvent} when
|
||||
* {@link CloudEurekaClient#onCacheRefreshed()} is called.
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@CommonsLog
|
||||
public class CloudEurekaClient extends DiscoveryClient {
|
||||
|
||||
private final AtomicLong cacheRefreshedCount = new AtomicLong(0);
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager,
|
||||
EurekaClientConfig config, ApplicationContext context) {
|
||||
this(applicationInfoManager, config, null, context);
|
||||
}
|
||||
|
||||
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager,
|
||||
EurekaClientConfig config,
|
||||
DiscoveryClientOptionalArgs args,
|
||||
ApplicationContext context) {
|
||||
super(applicationInfoManager, config, args);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCacheRefreshed() {
|
||||
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.context.publishEvent(new HeartbeatEvent(this, newCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
public class CloudEurkeaTransportConfig implements EurekaTransportConfig {
|
||||
|
||||
private int sessionedClientReconnectIntervalSeconds = 20 * 60;
|
||||
|
||||
private double retryableClientQuarantineRefreshPercentage = 0.66;
|
||||
|
||||
private int bootstrapResolverRefreshIntervalSeconds = 5 * 60;
|
||||
|
||||
private int applicationsResolverDataStalenessThresholdSeconds = 5 * 60;
|
||||
|
||||
private int asyncResolverRefreshIntervalMs = 5 * 60 * 1000;
|
||||
|
||||
private int asyncResolverWarmUpTimeoutMs = 5000;
|
||||
|
||||
private int asyncExecutorThreadPoolSize = 5;
|
||||
|
||||
private String readClusterVip;
|
||||
|
||||
private boolean bootstrapResolverForQuery = true;
|
||||
|
||||
@Override
|
||||
public boolean useBootstrapResolverForQuery() {
|
||||
return this.bootstrapResolverForQuery;
|
||||
}
|
||||
}
|
||||
-226
@@ -1,226 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.client.CommonsClientAutoConfiguration;
|
||||
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.context.scope.refresh.RefreshScope;
|
||||
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.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.DiscoveryClient.DiscoveryClientOptionalArgs;
|
||||
import com.netflix.discovery.EurekaClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
import static org.springframework.cloud.util.IdUtils.getDefaultInstanceId;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass(EurekaClientConfig.class)
|
||||
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
|
||||
@AutoConfigureBefore({ NoopDiscoveryClientAutoConfiguration.class,
|
||||
CommonsClientAutoConfiguration.class })
|
||||
@AutoConfigureAfter(RefreshAutoConfiguration.class)
|
||||
public class EurekaClientAutoConfiguration {
|
||||
|
||||
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
|
||||
int nonSecurePort;
|
||||
|
||||
@Value("${management.port:${MANAGEMENT_PORT:${PORT:8080}}}")
|
||||
int managementPort;
|
||||
|
||||
@Value("${eureka.instance.hostname:${EUREKA_INSTANCE_HOSTNAME:}}")
|
||||
String hostname;
|
||||
|
||||
@Autowired
|
||||
ConfigurableEnvironment env;
|
||||
|
||||
@Bean
|
||||
public HasFeatures eurekaFeature() {
|
||||
return HasFeatures.namedFeature("Eureka Client", EurekaClient.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = EurekaClientConfig.class, search = SearchStrategy.CURRENT)
|
||||
public EurekaClientConfigBean eurekaClientConfigBean() {
|
||||
return new EurekaClientConfigBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)
|
||||
public EurekaInstanceConfigBean eurekaInstanceConfigBean() {
|
||||
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean();
|
||||
instance.setNonSecurePort(this.nonSecurePort);
|
||||
instance.setInstanceId(getDefaultInstanceId(this.env));
|
||||
if (this.managementPort != this.nonSecurePort && this.managementPort != 0) {
|
||||
if (StringUtils.hasText(this.hostname)) {
|
||||
instance.setHostname(this.hostname);
|
||||
}
|
||||
String scheme = instance.getSecurePortEnabled() ? "https" : "http";
|
||||
instance.setStatusPageUrl(scheme + "://" + instance.getHostname() + ":"
|
||||
+ this.managementPort + instance.getStatusPageUrlPath());
|
||||
instance.setHealthCheckUrl(scheme + "://" + instance.getHostname() + ":"
|
||||
+ this.managementPort + instance.getHealthCheckUrlPath());
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DiscoveryClient discoveryClient(EurekaInstanceConfig config,
|
||||
EurekaClient client) {
|
||||
return new EurekaDiscoveryClient(config, client);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingRefreshScope
|
||||
protected static class EurekaClientConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Autowired(required = false)
|
||||
private DiscoveryClientOptionalArgs optionalArgs;
|
||||
|
||||
@Bean(destroyMethod = "shutdown")
|
||||
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
|
||||
public EurekaClient eurekaClient(ApplicationInfoManager applicationInfoManager,
|
||||
EurekaClientConfig config) {
|
||||
return new CloudEurekaClient(applicationInfoManager, config,
|
||||
this.optionalArgs, this.context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT)
|
||||
public ApplicationInfoManager eurekaApplicationInfoManager(
|
||||
EurekaInstanceConfig config) {
|
||||
InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
|
||||
return new ApplicationInfoManager(config, instanceInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnRefreshScope
|
||||
protected static class RefreshableEurekaClientConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Autowired(required = false)
|
||||
private DiscoveryClientOptionalArgs optionalArgs;
|
||||
|
||||
@Bean(destroyMethod = "shutdown")
|
||||
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
|
||||
@org.springframework.cloud.context.config.annotation.RefreshScope
|
||||
public EurekaClient eurekaClient(ApplicationInfoManager applicationInfoManager,
|
||||
EurekaClientConfig config, EurekaInstanceConfig instance) {
|
||||
applicationInfoManager.getInfo(); // force initialization
|
||||
return new CloudEurekaClient(applicationInfoManager, config,
|
||||
this.optionalArgs, this.context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT)
|
||||
@org.springframework.cloud.context.config.annotation.RefreshScope
|
||||
public ApplicationInfoManager eurekaApplicationInfoManager(
|
||||
EurekaInstanceConfig config) {
|
||||
InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
|
||||
return new ApplicationInfoManager(config, instanceInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Conditional(OnMissingRefreshScopeCondition.class)
|
||||
@interface ConditionalOnMissingRefreshScope {
|
||||
|
||||
}
|
||||
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Conditional(OnRefreshScopeCondition.class)
|
||||
@interface ConditionalOnRefreshScope {
|
||||
|
||||
}
|
||||
|
||||
private static class OnMissingRefreshScopeCondition extends AnyNestedCondition {
|
||||
|
||||
public OnMissingRefreshScopeCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnMissingClass("org.springframework.cloud.context.scope.refresh.RefreshScope")
|
||||
static class MissingClass {
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean(RefreshAutoConfiguration.class)
|
||||
static class MissingScope {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class OnRefreshScopeCondition extends AllNestedConditions {
|
||||
|
||||
public OnRefreshScopeCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnClass(RefreshScope.class)
|
||||
@ConditionalOnBean(RefreshAutoConfiguration.class)
|
||||
static class FoundScope {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-233
@@ -1,233 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
|
||||
import com.netflix.appinfo.EurekaAccept;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(EurekaClientConfigBean.PREFIX)
|
||||
public class EurekaClientConfigBean implements EurekaClientConfig, EurekaConstants {
|
||||
|
||||
public static final String PREFIX = "eureka.client";
|
||||
|
||||
@Autowired(required = false)
|
||||
PropertyResolver propertyResolver;
|
||||
|
||||
public static final String DEFAULT_URL = "http://localhost:8761"
|
||||
+ DEFAULT_PREFIX + "/";
|
||||
|
||||
public static final String DEFAULT_ZONE = "defaultZone";
|
||||
|
||||
private static final int MINUTES = 60;
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
private EurekaTransportConfig transport = new CloudEurkeaTransportConfig();
|
||||
|
||||
private int registryFetchIntervalSeconds = 30;
|
||||
|
||||
private int instanceInfoReplicationIntervalSeconds = 30;
|
||||
|
||||
private int initialInstanceInfoReplicationIntervalSeconds = 40;
|
||||
|
||||
private int eurekaServiceUrlPollIntervalSeconds = 5 * MINUTES;
|
||||
|
||||
private String proxyPort;
|
||||
|
||||
private String proxyHost;
|
||||
|
||||
private String proxyUserName;
|
||||
|
||||
private String proxyPassword;
|
||||
|
||||
private int eurekaServerReadTimeoutSeconds = 8;
|
||||
|
||||
private int eurekaServerConnectTimeoutSeconds = 5;
|
||||
|
||||
private String backupRegistryImpl;
|
||||
|
||||
private int eurekaServerTotalConnections = 200;
|
||||
|
||||
private int eurekaServerTotalConnectionsPerHost = 50;
|
||||
|
||||
private String eurekaServerURLContext;
|
||||
|
||||
private String eurekaServerPort;
|
||||
|
||||
private String eurekaServerDNSName;
|
||||
|
||||
private String region = "us-east-1";
|
||||
|
||||
private int eurekaConnectionIdleTimeoutSeconds = 30;
|
||||
|
||||
private String registryRefreshSingleVipAddress;
|
||||
|
||||
private int heartbeatExecutorThreadPoolSize = 2;
|
||||
|
||||
private int heartbeatExecutorExponentialBackOffBound = 10;
|
||||
|
||||
private int cacheRefreshExecutorThreadPoolSize = 2;
|
||||
|
||||
private int cacheRefreshExecutorExponentialBackOffBound = 10;
|
||||
|
||||
private Map<String, String> serviceUrl = new HashMap<>();
|
||||
{
|
||||
this.serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
|
||||
}
|
||||
|
||||
private boolean gZipContent = true;
|
||||
|
||||
private boolean useDnsForFetchingServiceUrls = false;
|
||||
|
||||
private boolean registerWithEureka = true;
|
||||
|
||||
private boolean preferSameZoneEureka = true;
|
||||
|
||||
private boolean logDeltaDiff;
|
||||
|
||||
private boolean disableDelta;
|
||||
|
||||
private String fetchRemoteRegionsRegistry;
|
||||
|
||||
private Map<String, String> availabilityZones = new HashMap<>();
|
||||
|
||||
private boolean filterOnlyUpInstances = true;
|
||||
|
||||
private boolean fetchRegistry = true;
|
||||
|
||||
private String dollarReplacement = "_-";
|
||||
|
||||
private String escapeCharReplacement = "__";
|
||||
|
||||
private boolean allowRedirects = false;
|
||||
|
||||
private boolean onDemandUpdateStatusChange = true;
|
||||
|
||||
private String encoderName;
|
||||
|
||||
private String decoderName;
|
||||
|
||||
private String clientDataAccept = EurekaAccept.full.name();
|
||||
|
||||
@Override
|
||||
public boolean shouldGZipContent() {
|
||||
return this.gZipContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUseDnsForFetchingServiceUrls() {
|
||||
return this.useDnsForFetchingServiceUrls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRegisterWithEureka() {
|
||||
return this.registerWithEureka;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPreferSameZoneEureka() {
|
||||
return this.preferSameZoneEureka;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLogDeltaDiff() {
|
||||
return this.logDeltaDiff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDisableDelta() {
|
||||
return this.disableDelta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fetchRegistryForRemoteRegions() {
|
||||
return this.fetchRemoteRegionsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailabilityZones(String region) {
|
||||
String value = this.availabilityZones.get(region);
|
||||
if (value == null) {
|
||||
value = DEFAULT_ZONE;
|
||||
}
|
||||
return value.split(",");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getEurekaServerServiceUrls(String myZone) {
|
||||
String serviceUrls = this.serviceUrl.get(myZone);
|
||||
if (serviceUrls == null || serviceUrls.isEmpty()) {
|
||||
serviceUrls = this.serviceUrl.get(DEFAULT_ZONE);
|
||||
}
|
||||
if (serviceUrls != null) {
|
||||
return Arrays.asList(serviceUrls.split(","));
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilterOnlyUpInstances() {
|
||||
return this.filterOnlyUpInstances;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFetchRegistry() {
|
||||
return this.fetchRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowRedirects() {
|
||||
return this.allowRedirects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOnDemandUpdateStatusChange() {
|
||||
return this.onDemandUpdateStatusChange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExperimental(String name) {
|
||||
if (propertyResolver != null) {
|
||||
return propertyResolver.getProperty(PREFIX + ".experimental." + name,
|
||||
String.class, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaTransportConfig getTransportConfig() {
|
||||
return getTransport();
|
||||
}
|
||||
}
|
||||
-220
@@ -1,220 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.health.HealthAggregator;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
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.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.ContextClosedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.appinfo.HealthCheckHandler;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.discovery.EurekaClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
* @author Jon Schneider
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass(EurekaClientConfig.class)
|
||||
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
|
||||
@CommonsLog
|
||||
public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Ordered {
|
||||
|
||||
private AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
||||
private int order = 0;
|
||||
|
||||
private AtomicInteger port = new AtomicInteger(0);
|
||||
|
||||
@Autowired
|
||||
private CloudEurekaInstanceConfig instanceConfig;
|
||||
|
||||
@Autowired(required = false)
|
||||
private HealthCheckHandler healthCheckHandler;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private ApplicationInfoManager applicationInfoManager;
|
||||
|
||||
@Autowired
|
||||
private EurekaClient eurekaClient;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
// only set the port if the nonSecurePort is 0 and this.port != 0
|
||||
if (this.port.get() != 0 && this.instanceConfig.getNonSecurePort() == 0) {
|
||||
this.instanceConfig.setNonSecurePort(this.port.get());
|
||||
}
|
||||
|
||||
// only initialize if nonSecurePort is greater than 0 and it isn't already running
|
||||
// because of containerPortInitializer below
|
||||
if (!this.running.get() && this.instanceConfig.getNonSecurePort() > 0) {
|
||||
|
||||
maybeInitializeClient();
|
||||
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Registering application " + this.instanceConfig.getAppname()
|
||||
+ " with eureka with status "
|
||||
+ this.instanceConfig.getInitialStatus());
|
||||
}
|
||||
|
||||
this.applicationInfoManager
|
||||
.setInstanceStatus(this.instanceConfig.getInitialStatus());
|
||||
|
||||
if (this.healthCheckHandler != null) {
|
||||
this.eurekaClient.registerHealthCheck(this.healthCheckHandler);
|
||||
}
|
||||
this.context.publishEvent(
|
||||
new InstanceRegisteredEvent<>(this, this.instanceConfig));
|
||||
this.running.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeInitializeClient() {
|
||||
// force initialization of possibly scoped proxies
|
||||
this.applicationInfoManager.getInfo();
|
||||
this.eurekaClient.getApplications();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (this.applicationInfoManager.getInfo() != null) {
|
||||
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Unregistering application " + this.instanceConfig.getAppname()
|
||||
+ " with eureka with status DOWN");
|
||||
}
|
||||
|
||||
this.applicationInfoManager.setInstanceStatus(InstanceStatus.DOWN);
|
||||
}
|
||||
this.running.set(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return this.running.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoStartup() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(Runnable callback) {
|
||||
stop();
|
||||
callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
@EventListener(EmbeddedServletContainerInitializedEvent.class)
|
||||
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
|
||||
// TODO: take SSL into account when Spring Boot 1.2 is available
|
||||
int localPort = event.getEmbeddedServletContainer().getPort();
|
||||
if (this.port.get() == 0) {
|
||||
log.info("Updating port to " + localPort);
|
||||
this.port.compareAndSet(0, localPort);
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(RefreshScopeRefreshedEvent.class)
|
||||
protected static class EurekaClientConfigurationRefresher {
|
||||
@Autowired
|
||||
private EurekaDiscoveryClientConfiguration clientConfig;
|
||||
|
||||
@EventListener(RefreshScopeRefreshedEvent.class)
|
||||
public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
|
||||
// register in case meta data changed
|
||||
this.clientConfig.stop();
|
||||
this.clientConfig.start();
|
||||
}
|
||||
}
|
||||
|
||||
@EventListener(ContextClosedEvent.class)
|
||||
public void onApplicationEvent(ContextClosedEvent event) {
|
||||
// register in case meta data changed
|
||||
stop();
|
||||
this.eurekaClient.shutdown();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Endpoint.class)
|
||||
protected static class EurekaHealthIndicatorConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public EurekaHealthIndicator eurekaHealthIndicator(EurekaClient eurekaClient,
|
||||
EurekaInstanceConfig instanceConfig, EurekaClientConfig clientConfig) {
|
||||
return new EurekaHealthIndicator(eurekaClient, instanceConfig, clientConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false)
|
||||
@ConditionalOnBean(HealthIndicator.class)
|
||||
protected static class EurekaHealthCheckHandlerConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private HealthAggregator healthAggregator = new OrderedHealthAggregator();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(HealthCheckHandler.class)
|
||||
public EurekaHealthCheckHandler eurekaHealthCheckHandler() {
|
||||
return new EurekaHealthCheckHandler(this.healthAggregator);
|
||||
}
|
||||
}
|
||||
}
|
||||
-98
@@ -1,98 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import static com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.netflix.appinfo.HealthCheckHandler;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
* @see HealthCheckHandler
|
||||
* @see HealthAggregator
|
||||
*/
|
||||
public class EurekaHealthCheckHandler implements HealthCheckHandler, ApplicationContextAware, InitializingBean {
|
||||
|
||||
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 final CompositeHealthIndicator healthIndicator;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public EurekaHealthCheckHandler(HealthAggregator healthAggregator) {
|
||||
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
|
||||
this.healthIndicator = new CompositeHealthIndicator(healthAggregator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
final Map<String, HealthIndicator> healthIndicators = applicationContext.getBeansOfType(HealthIndicator.class);
|
||||
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
|
||||
healthIndicator.addHealthIndicator(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceStatus getStatus(InstanceStatus instanceStatus) {
|
||||
return getHealthStatus();
|
||||
}
|
||||
|
||||
protected InstanceStatus getHealthStatus() {
|
||||
final Status status = healthIndicator.health().getStatus();
|
||||
return mapToInstanceStatus(status);
|
||||
}
|
||||
|
||||
protected InstanceStatus mapToInstanceStatus(Status status) {
|
||||
if (!STATUS_MAPPING.containsKey(status)) {
|
||||
return InstanceStatus.UNKNOWN;
|
||||
}
|
||||
return STATUS_MAPPING.get(status);
|
||||
}
|
||||
}
|
||||
-141
@@ -1,141 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.util.InetUtils.HostInfo;
|
||||
|
||||
import com.netflix.appinfo.DataCenterInfo;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.appinfo.MyDataCenterInfo;
|
||||
|
||||
import static org.springframework.cloud.util.InetUtils.getFirstNonLoopbackHostInfo;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("eureka.instance")
|
||||
public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig {
|
||||
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
@Setter(AccessLevel.PRIVATE)
|
||||
private HostInfo hostInfo = getFirstNonLoopbackHostInfo();
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appname = "unknown";
|
||||
|
||||
private String appGroupName;
|
||||
|
||||
private boolean instanceEnabledOnit;
|
||||
|
||||
private int nonSecurePort = 80;
|
||||
|
||||
private int securePort = 443;
|
||||
|
||||
private boolean nonSecurePortEnabled = true;
|
||||
|
||||
private boolean securePortEnabled;
|
||||
|
||||
private int leaseRenewalIntervalInSeconds = 30;
|
||||
|
||||
private int leaseExpirationDurationInSeconds = 90;
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String virtualHostName;
|
||||
|
||||
private String instanceId;
|
||||
|
||||
private String secureVirtualHostName;
|
||||
|
||||
private String aSGName;
|
||||
|
||||
private Map<String, String> metadataMap = new HashMap<>();
|
||||
|
||||
private DataCenterInfo dataCenterInfo = new MyDataCenterInfo(
|
||||
DataCenterInfo.Name.MyOwn);
|
||||
|
||||
private String ipAddress = this.hostInfo.getIpAddress();
|
||||
|
||||
private String statusPageUrlPath = "/info";
|
||||
|
||||
private String statusPageUrl;
|
||||
|
||||
private String homePageUrlPath = "/";
|
||||
|
||||
private String homePageUrl;
|
||||
|
||||
private String healthCheckUrlPath = "/health";
|
||||
|
||||
private String healthCheckUrl;
|
||||
|
||||
private String secureHealthCheckUrl;
|
||||
|
||||
private String namespace = "eureka";
|
||||
|
||||
private String hostname = this.hostInfo.getHostname();
|
||||
|
||||
private boolean preferIpAddress = false;
|
||||
|
||||
private InstanceStatus initialStatus = InstanceStatus.UP;
|
||||
|
||||
public String getHostname() {
|
||||
return getHostName(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceId() {
|
||||
if (this.instanceId == null && this.metadataMap != null) {
|
||||
return this.metadataMap.get("instanceId");
|
||||
}
|
||||
return this.instanceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSecurePortEnabled() {
|
||||
return this.securePortEnabled;
|
||||
}
|
||||
|
||||
public void setHostname(String hostname) {
|
||||
this.hostname = hostname;
|
||||
this.hostInfo.override = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostName(boolean refresh) {
|
||||
if (refresh) {
|
||||
boolean originalOverride = this.hostInfo.override;
|
||||
this.hostInfo = getFirstNonLoopbackHostInfo();
|
||||
this.hostInfo.setOverride(originalOverride);
|
||||
this.ipAddress = this.hostInfo.getIpAddress();
|
||||
if (!this.hostInfo.override) {
|
||||
this.hostname = this.hostInfo.getHostname();
|
||||
}
|
||||
}
|
||||
return this.preferIpAddress ? this.ipAddress : this.hostname;
|
||||
}
|
||||
}
|
||||
-84
@@ -1,84 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collection;
|
||||
|
||||
import feign.MethodMetadata;
|
||||
|
||||
/**
|
||||
* Feign contract method parameter processor.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
public interface AnnotatedParameterProcessor {
|
||||
|
||||
/**
|
||||
* Retrieves the processor supported annotation type.
|
||||
*
|
||||
* @return the annotation type
|
||||
*/
|
||||
Class<? extends Annotation> getAnnotationType();
|
||||
|
||||
/**
|
||||
* Process the annotated parameter.
|
||||
*
|
||||
* @param context the parameter context
|
||||
* @param annotation the annotation instance
|
||||
* @return whether the parameter is http
|
||||
*/
|
||||
boolean processArgument(AnnotatedParameterContext context, Annotation annotation);
|
||||
|
||||
/**
|
||||
* Specifies the parameter context.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
interface AnnotatedParameterContext {
|
||||
|
||||
/**
|
||||
* Retrieves the method metadata.
|
||||
*
|
||||
* @return the method metadata
|
||||
*/
|
||||
MethodMetadata getMethodMetadata();
|
||||
|
||||
/**
|
||||
* Retrieves the index of the parameter.
|
||||
*
|
||||
* @return the parameter index
|
||||
*/
|
||||
int getParameterIndex();
|
||||
|
||||
/**
|
||||
* Sets the parameter name.
|
||||
*
|
||||
* @param name the name of the parameter
|
||||
*/
|
||||
void setParameterName(String name);
|
||||
|
||||
/**
|
||||
* Sets the template parameter.
|
||||
*
|
||||
* @param name the template parameter
|
||||
* @param rest the existing parameter values
|
||||
* @return parameters
|
||||
*/
|
||||
Collection<String> setTemplateParameter(String name, Collection<String> rest);
|
||||
}
|
||||
}
|
||||
-88
@@ -1,88 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Scans for interfaces that declare they are feign clients (via {@link FeignClient
|
||||
* <code>@FeignClient</code>}). Configures component scanning directives for use with
|
||||
* {@link org.springframework.context.annotation.Configuration
|
||||
* <code>@Configuration</code>} classes.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
* @since 1.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@Import(FeignClientsRegistrar.class)
|
||||
public @interface EnableFeignClients {
|
||||
|
||||
/**
|
||||
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
|
||||
* declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of
|
||||
* {@code @ComponentScan(basePackages="org.my.pkg")}.
|
||||
* @return the array of 'basePackages'.
|
||||
*/
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* Base packages to scan for annotated components.
|
||||
* <p>
|
||||
* {@link #value()} is an alias for (and mutually exclusive with) this attribute.
|
||||
* <p>
|
||||
* Use {@link #basePackageClasses()} for a type-safe alternative to String-based
|
||||
* package names.
|
||||
*
|
||||
* @return the array of 'basePackages'.
|
||||
*/
|
||||
String[] basePackages() default {};
|
||||
|
||||
/**
|
||||
* Type-safe alternative to {@link #basePackages()} for specifying the packages to
|
||||
* scan for annotated components. The package of each class specified will be scanned.
|
||||
* <p>
|
||||
* Consider creating a special no-op marker class or interface in each package that
|
||||
* serves no purpose other than being referenced by this attribute.
|
||||
*
|
||||
* @return the array of 'basePackageClasses'.
|
||||
*/
|
||||
Class<?>[] basePackageClasses() default {};
|
||||
|
||||
/**
|
||||
* A custom <code>@Configuration</code> for all feign clients. Can contain override
|
||||
* <code>@Bean</code> definition for the pieces that make up the client, for instance
|
||||
* {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
|
||||
*
|
||||
* @see FeignClientsConfiguration for the defaults
|
||||
*/
|
||||
Class<?>[] defaultConfiguration() default {};
|
||||
|
||||
/**
|
||||
* List of classes annotated with @FeignClient. If not empty, disables classpath scanning.
|
||||
* @return
|
||||
*/
|
||||
Class<?>[] clients() default {};
|
||||
}
|
||||
-52
@@ -1,52 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.client.actuator.HasFeatures;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import feign.Feign;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Julien Roy
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(Feign.class)
|
||||
public class FeignAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<FeignClientSpecification> configurations = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
public HasFeatures feignFeature() {
|
||||
return HasFeatures.namedFeature("Feign", Feign.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FeignClientFactory feignClientFactory() {
|
||||
FeignClientFactory factory = new FeignClientFactory();
|
||||
factory.setConfigurations(this.configurations);
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
-79
@@ -1,79 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
/**
|
||||
* Annotation for interfaces declaring that a REST client with that interface should be
|
||||
* created (e.g. for autowiring into another component). If ribbon is available it will be
|
||||
* used to load balance the backend requests, and the load balancer can be configured
|
||||
* using a <code>@RibbonClient</code> with the same name (i.e. value) as the feign client.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface FeignClient {
|
||||
|
||||
/**
|
||||
* The serviceId with optional protocol prefix. Synonym for {@link #serviceId()
|
||||
* serviceId}. Either serviceId or url must be specified but not both. Can be
|
||||
* specified as property key, eg: ${propertyKey}.
|
||||
*/
|
||||
@AliasFor("name")
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* The serviceId with optional protocol prefix. Synonym for {@link #value() value}.
|
||||
* Either serviceId or url must be specified but not both. Can be
|
||||
* specified as property key, eg: ${propertyKey}.
|
||||
*
|
||||
* @deprecated use {@link #name() name} instead
|
||||
*/
|
||||
@Deprecated
|
||||
String serviceId() default "";
|
||||
|
||||
@AliasFor("value")
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* An absolute URL or resolvable hostname (the protocol is optional).
|
||||
*/
|
||||
String url() default "";
|
||||
|
||||
/**
|
||||
* Whether 404s should be decoded instead of throwing FeignExceptions
|
||||
*/
|
||||
boolean decode404() default false;
|
||||
|
||||
/**
|
||||
* A custom <code>@Configuration</code> for the feign client. Can contain override
|
||||
* <code>@Bean</code> definition for the pieces that make up the client, for instance
|
||||
* {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
|
||||
*
|
||||
* @see FeignClientsConfiguration for the defaults
|
||||
*/
|
||||
Class<?>[] configuration() default {};
|
||||
}
|
||||
-167
@@ -1,167 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
import feign.Request;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.Retryer;
|
||||
import feign.Target;
|
||||
import feign.Target.HardCodedTarget;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean, ApplicationContextAware {
|
||||
|
||||
private Class<?> type;
|
||||
|
||||
private String name;
|
||||
|
||||
private String url;
|
||||
|
||||
private boolean decode404;
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.hasText(this.name, "Name must be set");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected Feign.Builder feign(FeignClientFactory factory) {
|
||||
Logger logger = getOptional(factory, Logger.class);
|
||||
|
||||
if (logger == null) {
|
||||
logger = new Slf4jLogger(this.type);
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
Feign.Builder builder = get(factory, Feign.Builder.class)
|
||||
// required values
|
||||
.logger(logger)
|
||||
.encoder(get(factory, Encoder.class))
|
||||
.decoder(get(factory, Decoder.class))
|
||||
.contract(get(factory, Contract.class));
|
||||
// @formatter:on
|
||||
|
||||
// optional values
|
||||
Logger.Level level = getOptional(factory, Logger.Level.class);
|
||||
if (level != null) {
|
||||
builder.logLevel(level);
|
||||
}
|
||||
Retryer retryer = getOptional(factory, Retryer.class);
|
||||
if (retryer != null) {
|
||||
builder.retryer(retryer);
|
||||
}
|
||||
ErrorDecoder errorDecoder = getOptional(factory, ErrorDecoder.class);
|
||||
if (errorDecoder != null) {
|
||||
builder.errorDecoder(errorDecoder);
|
||||
}
|
||||
Request.Options options = getOptional(factory, Request.Options.class);
|
||||
if (options != null) {
|
||||
builder.options(options);
|
||||
}
|
||||
Map<String, RequestInterceptor> requestInterceptors = factory.getInstances(this.name, RequestInterceptor.class);
|
||||
if (requestInterceptors != null) {
|
||||
builder.requestInterceptors(requestInterceptors.values());
|
||||
}
|
||||
|
||||
if (decode404) {
|
||||
builder.decode404();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected <T> T get(FeignClientFactory factory, Class<T> type) {
|
||||
T instance = factory.getInstance(this.name, type);
|
||||
if (instance == null) {
|
||||
throw new IllegalStateException("No bean found of type " + type + " for " + this.name);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected <T> T getOptional(FeignClientFactory factory, Class<T> type) {
|
||||
return factory.getInstance(this.name, type);
|
||||
}
|
||||
|
||||
protected <T> T loadBalance(Feign.Builder builder, FeignClientFactory factory, Target<T> target) {
|
||||
Client client = getOptional(factory, Client.class);
|
||||
if (client != null) {
|
||||
return builder.client(client).target(target);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-ribbon?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
FeignClientFactory factory = context.getBean(FeignClientFactory.class);
|
||||
|
||||
if (!StringUtils.hasText(this.url)) {
|
||||
String url;
|
||||
if (!this.name.startsWith("http")) {
|
||||
url = "http://" + this.name;
|
||||
} else {
|
||||
url = this.name;
|
||||
}
|
||||
return loadBalance(feign(factory), factory, new HardCodedTarget<>(this.type, this.name, url));
|
||||
}
|
||||
if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
|
||||
this.url = "http://" + this.url;
|
||||
}
|
||||
return feign(factory).target(new HardCodedTarget<>(this.type, this.name, this.url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
-109
@@ -1,109 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.autoconfigure.web.HttpMessageConverters;
|
||||
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
|
||||
import org.springframework.cloud.netflix.feign.support.SpringDecoder;
|
||||
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
|
||||
import org.springframework.cloud.netflix.feign.support.SpringMvcContract;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import feign.hystrix.HystrixFeign;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
public class FeignClientsConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AnnotatedParameterProcessor> parameterProcessors = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Decoder feignDecoder() {
|
||||
return new ResponseEntityDecoder(new SpringDecoder(messageConverters));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Encoder feignEncoder() {
|
||||
return new SpringEncoder(messageConverters);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Contract feignContract() {
|
||||
return new SpringMvcContract(parameterProcessors);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(HystrixCommand.class)
|
||||
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = true)
|
||||
public Feign.Builder feignHystrixBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false, havingValue = "false")
|
||||
public Feign.Builder feignBuilder() {
|
||||
return Feign.builder();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(ApacheHttpClient.class)
|
||||
protected static class HttpClientConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private HttpClient httpClient;
|
||||
|
||||
@ConditionalOnMissingBean
|
||||
public Client feignClient() {
|
||||
if (httpClient != null) {
|
||||
return new ApacheHttpClient(httpClient);
|
||||
}
|
||||
return new ApacheHttpClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
-374
@@ -1,374 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.AbstractClassTestingTypeFilter;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
public class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
ResourceLoaderAware, BeanClassLoaderAware {
|
||||
|
||||
// patterned after Spring Integration IntegrationComponentScanRegistrar
|
||||
// and RibbonClientsConfigurationRegistgrar
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public FeignClientsRegistrar() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
registerDefaultConfiguration(metadata, registry);
|
||||
registerFeignClients(metadata, registry);
|
||||
}
|
||||
|
||||
private void registerDefaultConfiguration(AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
Map<String, Object> defaultAttrs = metadata
|
||||
.getAnnotationAttributes(EnableFeignClients.class.getName(), true);
|
||||
|
||||
if (defaultAttrs != null && defaultAttrs.containsKey("defaultConfiguration")) {
|
||||
String name;
|
||||
if (metadata.hasEnclosingClass()) {
|
||||
name = "default." + metadata.getEnclosingClassName();
|
||||
}
|
||||
else {
|
||||
name = "default." + metadata.getClassName();
|
||||
}
|
||||
registerClientConfiguration(registry, name,
|
||||
defaultAttrs.get("defaultConfiguration"));
|
||||
}
|
||||
}
|
||||
|
||||
public void registerFeignClients(AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
ClassPathScanningCandidateComponentProvider scanner = getScanner();
|
||||
scanner.setResourceLoader(this.resourceLoader);
|
||||
|
||||
Set<String> basePackages;
|
||||
|
||||
Map<String, Object> attrs = metadata
|
||||
.getAnnotationAttributes(EnableFeignClients.class.getName());
|
||||
AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
|
||||
FeignClient.class);
|
||||
final Class<?>[] clients = attrs == null ? null
|
||||
: (Class<?>[]) attrs.get("clients");
|
||||
if (clients == null || clients.length == 0) {
|
||||
scanner.addIncludeFilter(annotationTypeFilter);
|
||||
basePackages = getBasePackages(metadata);
|
||||
}
|
||||
else {
|
||||
final Set<String> clientClasses = new HashSet<>();
|
||||
basePackages = new HashSet<>();
|
||||
for (Class<?> clazz : clients) {
|
||||
basePackages.add(ClassUtils.getPackageName(clazz));
|
||||
clientClasses.add(clazz.getCanonicalName());
|
||||
}
|
||||
AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {
|
||||
@Override
|
||||
protected boolean match(ClassMetadata metadata) {
|
||||
String cleaned = metadata.getClassName().replaceAll("\\$", ".");
|
||||
return clientClasses.contains(cleaned);
|
||||
}
|
||||
};
|
||||
scanner.addIncludeFilter(
|
||||
new AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));
|
||||
}
|
||||
|
||||
for (String basePackage : basePackages) {
|
||||
Set<BeanDefinition> candidateComponents = scanner
|
||||
.findCandidateComponents(basePackage);
|
||||
for (BeanDefinition candidateComponent : candidateComponents) {
|
||||
if (candidateComponent instanceof AnnotatedBeanDefinition) {
|
||||
// verify annotated class is an interface
|
||||
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
|
||||
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
|
||||
Assert.isTrue(annotationMetadata.isInterface(),
|
||||
"@FeignClient can only be specified on an interface");
|
||||
|
||||
Map<String, Object> attributes = annotationMetadata
|
||||
.getAnnotationAttributes(
|
||||
FeignClient.class.getCanonicalName());
|
||||
|
||||
String name = getClientName(attributes);
|
||||
registerClientConfiguration(registry, name,
|
||||
attributes.get("configuration"));
|
||||
|
||||
registerFeignClient(registry, annotationMetadata, attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerFeignClient(BeanDefinitionRegistry registry,
|
||||
AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
|
||||
String className = annotationMetadata.getClassName();
|
||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(FeignClientFactoryBean.class);
|
||||
validate(attributes);
|
||||
definition.addPropertyValue("url", getUrl(attributes));
|
||||
definition.addPropertyValue("name", getServiceId(attributes));
|
||||
definition.addPropertyValue("type", className);
|
||||
definition.addPropertyValue("decode404", attributes.get("decode404"));
|
||||
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
|
||||
String beanName = StringUtils
|
||||
.uncapitalize(className.substring(className.lastIndexOf(".") + 1));
|
||||
BeanDefinitionHolder holder = new BeanDefinitionHolder(
|
||||
definition.getBeanDefinition(), beanName);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
|
||||
}
|
||||
|
||||
private void validate(Map<String, Object> attributes) {
|
||||
if (StringUtils.hasText((String) attributes.get("value"))) {
|
||||
Assert.isTrue(!StringUtils.hasText((String) attributes.get("serviceId")),
|
||||
"Either serviceId or value can be specified, but not both");
|
||||
}
|
||||
}
|
||||
|
||||
private String getServiceId(Map<String, Object> attributes) {
|
||||
String name = (String) attributes.get("serviceId");
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = (String) attributes.get("name");
|
||||
}
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = (String) attributes.get("value");
|
||||
}
|
||||
name = resolve(name);
|
||||
if (!StringUtils.hasText(name)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String host = null;
|
||||
try {
|
||||
host = new URI("http://" + name).getHost();
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
}
|
||||
Assert.state(host != null, "Service id not legal hostname (" + name + ")");
|
||||
return name;
|
||||
}
|
||||
|
||||
private String resolve(String value) {
|
||||
if (StringUtils.hasText(value)
|
||||
&& this.resourceLoader instanceof ConfigurableApplicationContext) {
|
||||
return ((ConfigurableApplicationContext) this.resourceLoader).getEnvironment()
|
||||
.resolvePlaceholders(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private String getUrl(Map<String, Object> attributes) {
|
||||
String url = resolve((String) attributes.get("url"));
|
||||
if (StringUtils.hasText(url)) {
|
||||
if (!url.contains("://")) {
|
||||
url = "http://" + url;
|
||||
}
|
||||
try {
|
||||
new URL(url);
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new IllegalArgumentException(url + " is malformed", e);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
protected ClassPathScanningCandidateComponentProvider getScanner() {
|
||||
return new ClassPathScanningCandidateComponentProvider(false) {
|
||||
|
||||
@Override
|
||||
protected boolean isCandidateComponent(
|
||||
AnnotatedBeanDefinition beanDefinition) {
|
||||
if (beanDefinition.getMetadata().isIndependent()) {
|
||||
// TODO until SPR-11711 will be resolved
|
||||
if (beanDefinition.getMetadata().isInterface()
|
||||
&& beanDefinition.getMetadata()
|
||||
.getInterfaceNames().length == 1
|
||||
&& Annotation.class.getName().equals(beanDefinition
|
||||
.getMetadata().getInterfaceNames()[0])) {
|
||||
try {
|
||||
Class<?> target = ClassUtils.forName(
|
||||
beanDefinition.getMetadata().getClassName(),
|
||||
FeignClientsRegistrar.this.classLoader);
|
||||
return !target.isAnnotation();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
this.logger.error(
|
||||
"Could not load target class: "
|
||||
+ beanDefinition.getMetadata().getClassName(),
|
||||
ex);
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
|
||||
Map<String, Object> attributes = importingClassMetadata
|
||||
.getAnnotationAttributes(EnableFeignClients.class.getCanonicalName());
|
||||
|
||||
Set<String> basePackages = new HashSet<>();
|
||||
for (String pkg : (String[]) attributes.get("value")) {
|
||||
if (StringUtils.hasText(pkg)) {
|
||||
basePackages.add(pkg);
|
||||
}
|
||||
}
|
||||
for (String pkg : (String[]) attributes.get("basePackages")) {
|
||||
if (StringUtils.hasText(pkg)) {
|
||||
basePackages.add(pkg);
|
||||
}
|
||||
}
|
||||
for (Class<?> clazz : (Class[]) attributes.get("basePackageClasses")) {
|
||||
basePackages.add(ClassUtils.getPackageName(clazz));
|
||||
}
|
||||
|
||||
if (basePackages.isEmpty()) {
|
||||
basePackages.add(
|
||||
ClassUtils.getPackageName(importingClassMetadata.getClassName()));
|
||||
}
|
||||
return basePackages;
|
||||
}
|
||||
|
||||
private String getClientName(Map<String, Object> client) {
|
||||
if (client == null) {
|
||||
return null;
|
||||
}
|
||||
String value = (String) client.get("value");
|
||||
if (!StringUtils.hasText(value)) {
|
||||
value = (String) client.get("name");
|
||||
}
|
||||
if (!StringUtils.hasText(value)) {
|
||||
value = (String) client.get("serviceId");
|
||||
}
|
||||
if (StringUtils.hasText(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Either 'name' or 'value' must be provided in @"
|
||||
+ FeignClient.class.getSimpleName());
|
||||
}
|
||||
|
||||
private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,
|
||||
Object configuration) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(FeignClientSpecification.class);
|
||||
builder.addConstructorArgValue(name);
|
||||
builder.addConstructorArgValue(configuration);
|
||||
registry.registerBeanDefinition(
|
||||
name + "." + FeignClientSpecification.class.getSimpleName(),
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to create a {@link TypeFilter} that matches if all the delegates
|
||||
* match.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class AllTypeFilter implements TypeFilter {
|
||||
|
||||
private final List<TypeFilter> delegates;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AllTypeFilter} to match if all the given delegates match.
|
||||
*
|
||||
* @param delegates must not be {@literal null}.
|
||||
*/
|
||||
public AllTypeFilter(List<TypeFilter> delegates) {
|
||||
|
||||
Assert.notNull(delegates);
|
||||
this.delegates = delegates;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.core.type.filter.TypeFilter#match(org.springframework.core.
|
||||
* type.classreading.MetadataReader,
|
||||
* org.springframework.core.type.classreading.MetadataReaderFactory)
|
||||
*/
|
||||
@Override
|
||||
public boolean match(MetadataReader metadataReader,
|
||||
MetadataReaderFactory metadataReaderFactory) throws IOException {
|
||||
|
||||
for (TypeFilter filter : this.delegates) {
|
||||
if (!filter.match(metadataReader, metadataReaderFactory)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
-75
@@ -1,75 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
import feign.MethodMetadata;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
/**
|
||||
* {@link PathVariable} parameter processor.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
* @see AnnotatedParameterProcessor
|
||||
*/
|
||||
public class PathVariableParameterProcessor implements AnnotatedParameterProcessor {
|
||||
|
||||
private static final Class<PathVariable> ANNOTATION = PathVariable.class;
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> getAnnotationType() {
|
||||
return ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation) {
|
||||
String name = ANNOTATION.cast(annotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"PathVariable annotation was empty on param %s.", context.getParameterIndex());
|
||||
context.setParameterName(name);
|
||||
|
||||
MethodMetadata data = context.getMethodMetadata();
|
||||
String varName = '{' + name + '}';
|
||||
if (!data.template().url().contains(varName)
|
||||
&& !searchMapValues(data.template().queries(), varName)
|
||||
&& !searchMapValues(data.template().headers(), varName)) {
|
||||
data.formParams().add(name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private <K, V> boolean searchMapValues(Map<K, Collection<V>> map, V search) {
|
||||
Collection<Collection<V>> values = map.values();
|
||||
if (values == null) {
|
||||
return false;
|
||||
}
|
||||
for (Collection<V> entry : values) {
|
||||
if (entry.contains(search)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-57
@@ -1,57 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
import feign.MethodMetadata;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
/**
|
||||
* {@link RequestHeader} parameter processor.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
* @see AnnotatedParameterProcessor
|
||||
*/
|
||||
public class RequestHeaderParameterProcessor implements AnnotatedParameterProcessor {
|
||||
|
||||
private static final Class<RequestHeader> ANNOTATION = RequestHeader.class;
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> getAnnotationType() {
|
||||
return ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation) {
|
||||
String name = ANNOTATION.cast(annotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"RequestHeader.value() was empty on parameter %s", context.getParameterIndex());
|
||||
context.setParameterName(name);
|
||||
|
||||
MethodMetadata data = context.getMethodMetadata();
|
||||
Collection<String> header = context.setTemplateParameter(name, data.template().headers().get(name));
|
||||
data.template().header(name, header);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-57
@@ -1,57 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import feign.MethodMetadata;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
/**
|
||||
* {@link RequestParam} parameter processor.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
* @see AnnotatedParameterProcessor
|
||||
*/
|
||||
public class RequestParamParameterProcessor implements AnnotatedParameterProcessor {
|
||||
|
||||
private static final Class<RequestParam> ANNOTATION = RequestParam.class;
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> getAnnotationType() {
|
||||
return ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation) {
|
||||
String name = ANNOTATION.cast(annotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"RequestParam.value() was empty on parameter %s", context.getParameterIndex());
|
||||
context.setParameterName(name);
|
||||
|
||||
MethodMetadata data = context.getMethodMetadata();
|
||||
Collection<String> query = context.setTemplateParameter(name, data.template().queries().get(name));
|
||||
data.template().query(name, query);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.encoding;
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The base request interceptor.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
public abstract class BaseRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
/**
|
||||
* The encoding properties.
|
||||
*/
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
private final FeignClientEncodingProperties properties;
|
||||
|
||||
/**
|
||||
* Creates new instance of {@link BaseRequestInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected BaseRequestInterceptor(FeignClientEncodingProperties properties) {
|
||||
Assert.notNull(properties, "Properties can not be null");
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the header if it wasn't yet specified.
|
||||
*
|
||||
* @param requestTemplate the request
|
||||
* @param name the header name
|
||||
* @param values the header values
|
||||
*/
|
||||
protected void addHeader(RequestTemplate requestTemplate, String name, String... values) {
|
||||
|
||||
if (!requestTemplate.headers().containsKey(name)) {
|
||||
requestTemplate.header(name, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.encoding;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
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.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Configures the Feign response compression.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
* @see FeignAcceptGzipEncodingInterceptor
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(FeignClientEncodingProperties.class)
|
||||
@ConditionalOnClass(Feign.class)
|
||||
@ConditionalOnBean(ApacheHttpClient.class)
|
||||
@ConditionalOnProperty(value = "feign.compression.response.enabled", matchIfMissing = false)
|
||||
@AutoConfigureBefore(FeignAutoConfiguration.class)
|
||||
public class FeignAcceptGzipEncodingAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public FeignAcceptGzipEncodingInterceptor feignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
return new FeignAcceptGzipEncodingInterceptor(properties);
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.encoding;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
|
||||
/**
|
||||
* Enables the HTTP response payload compression by specifying the {@code Accept-Encoding} headers.
|
||||
* Although this does not yet mean that the requests will be compressed, it requires the remote server
|
||||
* to understand the header and be configured to compress responses. Still no all responses might be compressed
|
||||
* based on the media type matching and other factors like the response content length.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
public class FeignAcceptGzipEncodingInterceptor extends BaseRequestInterceptor {
|
||||
|
||||
/**
|
||||
* Creates new instance of {@link FeignAcceptGzipEncodingInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected FeignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
|
||||
addHeader(template, HttpEncoding.ACCEPT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING,
|
||||
HttpEncoding.DEFLATE_ENCODING);
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.encoding;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
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.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Configures the Feign request compression.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
* @see FeignContentGzipEncodingInterceptor
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(FeignClientEncodingProperties.class)
|
||||
@ConditionalOnClass(Feign.class)
|
||||
@ConditionalOnBean(ApacheHttpClient.class)
|
||||
@ConditionalOnProperty(value = "feign.compression.request.enabled", matchIfMissing = false)
|
||||
@AutoConfigureBefore(FeignAutoConfiguration.class)
|
||||
public class FeignContentGzipEncodingAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public FeignContentGzipEncodingInterceptor feignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
return new FeignContentGzipEncodingInterceptor(properties);
|
||||
}
|
||||
}
|
||||
-111
@@ -1,111 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.encoding;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Enables the HTTP request payload compression by specifying the {@code Content-Encoding} headers.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
public class FeignContentGzipEncodingInterceptor extends BaseRequestInterceptor {
|
||||
|
||||
/**
|
||||
* Creates new instance of {@link FeignContentGzipEncodingInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected FeignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
|
||||
if (requiresCompression(template)) {
|
||||
addHeader(template, HttpEncoding.CONTENT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING,
|
||||
HttpEncoding.DEFLATE_ENCODING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the request requires GZIP compression.
|
||||
*
|
||||
* @param template the request template
|
||||
* @return true if request requires compression, false otherwise
|
||||
*/
|
||||
private boolean requiresCompression(RequestTemplate template) {
|
||||
|
||||
final Map<String, Collection<String>> headers = template.headers();
|
||||
return matchesMimeType(headers.get(HttpEncoding.CONTENT_TYPE))
|
||||
&& contentLengthExceedThreshold(headers.get(HttpEncoding.CONTENT_LENGTH));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the request content length exceed configured minimum size.
|
||||
*
|
||||
* @param contentLength the content length header value
|
||||
* @return true if length is grater than minimum size, false otherwise
|
||||
*/
|
||||
private boolean contentLengthExceedThreshold(Collection<String> contentLength) {
|
||||
|
||||
try {
|
||||
if (contentLength.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String strLen = contentLength.iterator().next();
|
||||
final long length = Long.parseLong(strLen);
|
||||
return length > getProperties().getMinRequestSize();
|
||||
} catch (NumberFormatException ex) {
|
||||
// ignores the exception
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the content mime types matches the configures mime types.
|
||||
*
|
||||
* @param contentTypes the content types
|
||||
* @return true if any specified content type matches the request content types
|
||||
*/
|
||||
private boolean matchesMimeType(Collection<String> contentTypes) {
|
||||
if (contentTypes == null || contentTypes.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getProperties().getMimeTypes() == null || getProperties().getMimeTypes().length == 0) {
|
||||
// no specific mime types has been set - matching everything
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String mimeType : getProperties().getMimeTypes()) {
|
||||
if (contentTypes.contains(mimeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.encoding;
|
||||
|
||||
/**
|
||||
* Lists all constants used by Feign encoders.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
public interface HttpEncoding {
|
||||
|
||||
/**
|
||||
* The HTTP Content-Length header.
|
||||
*/
|
||||
String CONTENT_LENGTH = "Content-Length";
|
||||
|
||||
/**
|
||||
* The HTTP Content-Type header.
|
||||
*/
|
||||
String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
/**
|
||||
* The HTTP Accept-Encoding header.
|
||||
*/
|
||||
String ACCEPT_ENCODING_HEADER = "Accept-Encoding";
|
||||
|
||||
/**
|
||||
* The HTTP Content-Encoding header.
|
||||
*/
|
||||
String CONTENT_ENCODING_HEADER = "Content-Encoding";
|
||||
|
||||
/**
|
||||
* The GZIP encoding.
|
||||
*/
|
||||
String GZIP_ENCODING = "gzip";
|
||||
|
||||
/**
|
||||
* The Deflate encoding.
|
||||
*/
|
||||
String DEFLATE_ENCODING = "deflate";
|
||||
}
|
||||
-56
@@ -1,56 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
/**
|
||||
* Factory for SpringLoadBalancer instances that caches the entries created.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class CachingSpringLoadBalancerFactory {
|
||||
|
||||
private final SpringClientFactory factory;
|
||||
|
||||
private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap<>();
|
||||
|
||||
public CachingSpringLoadBalancerFactory(SpringClientFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public FeignLoadBalancer create(String clientName) {
|
||||
if (this.cache.containsKey(clientName)) {
|
||||
return this.cache.get(clientName);
|
||||
}
|
||||
IClientConfig config = this.factory.getClientConfig(clientName);
|
||||
ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
|
||||
ServerIntrospector serverIntrospector = this.factory.getInstance(clientName, ServerIntrospector.class);
|
||||
FeignLoadBalancer client = new FeignLoadBalancer(lb, config, serverIntrospector);
|
||||
this.cache.put(clientName, client);
|
||||
return client;
|
||||
}
|
||||
|
||||
}
|
||||
-183
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import com.netflix.client.AbstractLoadBalancerAwareClient;
|
||||
import com.netflix.client.ClientException;
|
||||
import com.netflix.client.ClientRequest;
|
||||
import com.netflix.client.IResponse;
|
||||
import com.netflix.client.RequestSpecificRetryHandler;
|
||||
import com.netflix.client.RetryHandler;
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Response;
|
||||
|
||||
public class FeignLoadBalancer extends
|
||||
AbstractLoadBalancerAwareClient<FeignLoadBalancer.RibbonRequest, FeignLoadBalancer.RibbonResponse> {
|
||||
|
||||
private final int connectTimeout;
|
||||
private final int readTimeout;
|
||||
private final IClientConfig clientConfig;
|
||||
private final ServerIntrospector serverIntrospector;
|
||||
|
||||
public FeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,
|
||||
ServerIntrospector serverIntrospector) {
|
||||
super(lb, clientConfig);
|
||||
this.setRetryHandler(RetryHandler.DEFAULT);
|
||||
this.clientConfig = clientConfig;
|
||||
this.connectTimeout = clientConfig.get(CommonClientConfigKey.ConnectTimeout);
|
||||
this.readTimeout = clientConfig.get(CommonClientConfigKey.ReadTimeout);
|
||||
this.serverIntrospector = serverIntrospector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
|
||||
throws IOException {
|
||||
Request.Options options;
|
||||
if (configOverride != null) {
|
||||
options = new Request.Options(
|
||||
configOverride.get(CommonClientConfigKey.ConnectTimeout,
|
||||
this.connectTimeout),
|
||||
(configOverride.get(CommonClientConfigKey.ReadTimeout,
|
||||
this.readTimeout)));
|
||||
}
|
||||
else {
|
||||
options = new Request.Options(this.connectTimeout, this.readTimeout);
|
||||
}
|
||||
Response response = request.client().execute(request.toRequest(), options);
|
||||
return new RibbonResponse(request.getUri(), response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
|
||||
RibbonRequest request, IClientConfig requestConfig) {
|
||||
if (this.clientConfig.get(CommonClientConfigKey.OkToRetryOnAllOperations,
|
||||
false)) {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
if (!request.toRequest().method().equals("GET")) {
|
||||
return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
else {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI reconstructURIWithServer(Server server, URI original) {
|
||||
String scheme = original.getScheme();
|
||||
if (!"https".equals(scheme) && (this.serverIntrospector.isSecure(server)
|
||||
|| this.clientConfig.get(CommonClientConfigKey.IsSecure, false))) {
|
||||
original = UriComponentsBuilder.fromUri(original).scheme("https").build()
|
||||
.toUri();
|
||||
}
|
||||
return super.reconstructURIWithServer(server, original);
|
||||
}
|
||||
|
||||
static class RibbonRequest extends ClientRequest implements Cloneable {
|
||||
|
||||
private final Request request;
|
||||
private final Client client;
|
||||
|
||||
RibbonRequest(Client client, Request request, URI uri) {
|
||||
this.client = client;
|
||||
this.request = request;
|
||||
setUri(uri);
|
||||
}
|
||||
|
||||
Request toRequest() {
|
||||
return new RequestTemplate().method(this.request.method())
|
||||
.append(getUri().toASCIIString()).headers(this.request.headers())
|
||||
.body(this.request.body(), this.request.charset()).request();
|
||||
}
|
||||
|
||||
Client client() {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new RibbonRequest(this.client, this.request, getUri());
|
||||
}
|
||||
}
|
||||
|
||||
static class RibbonResponse implements IResponse {
|
||||
|
||||
private final URI uri;
|
||||
private final Response response;
|
||||
|
||||
RibbonResponse(URI uri, Response response) {
|
||||
this.uri = uri;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPayload() throws ClientException {
|
||||
return this.response.body();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPayload() {
|
||||
return this.response.body() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return this.response.status() == 200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRequestedURI() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Collection<String>> getHeaders() {
|
||||
return this.response.headers();
|
||||
}
|
||||
|
||||
Response toResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (this.response != null && this.response.body() != null) {
|
||||
this.response.body().close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-109
@@ -1,109 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import feign.okhttp.OkHttpClient;
|
||||
|
||||
/**
|
||||
* Autoconfiguration to be activated if Feign is in use and needs to be use Ribbon as a
|
||||
* load balancer.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConditionalOnClass({ ILoadBalancer.class, Feign.class })
|
||||
@Configuration
|
||||
@AutoConfigureBefore(FeignAutoConfiguration.class)
|
||||
public class FeignRibbonClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public CachingSpringLoadBalancerFactory cachingLBClientFactory(
|
||||
SpringClientFactory factory) {
|
||||
return new CachingSpringLoadBalancerFactory(factory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory) {
|
||||
return new LoadBalancerFeignClient(new Client.Default(null, null), cachingFactory);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(ApacheHttpClient.class)
|
||||
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
|
||||
protected static class HttpClientConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private HttpClient httpClient;
|
||||
|
||||
@Autowired
|
||||
CachingSpringLoadBalancerFactory cachingFactory;
|
||||
|
||||
@Bean
|
||||
public Client feignClient() {
|
||||
ApacheHttpClient delegate;
|
||||
if (this.httpClient != null) {
|
||||
delegate = new ApacheHttpClient(this.httpClient);
|
||||
}
|
||||
else {
|
||||
delegate = new ApacheHttpClient();
|
||||
}
|
||||
return new LoadBalancerFeignClient(delegate, this.cachingFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(OkHttpClient.class)
|
||||
@ConditionalOnProperty(value = "feign.okhttp.enabled", matchIfMissing = true)
|
||||
protected static class OkHttpConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private com.squareup.okhttp.OkHttpClient okHttpClient;
|
||||
|
||||
@Autowired
|
||||
CachingSpringLoadBalancerFactory cachingFactory;
|
||||
|
||||
@Bean
|
||||
public Client feignClient() {
|
||||
OkHttpClient delegate;
|
||||
if (this.okHttpClient != null) {
|
||||
delegate = new OkHttpClient(this.okHttpClient);
|
||||
}
|
||||
else {
|
||||
delegate = new OkHttpClient();
|
||||
}
|
||||
return new LoadBalancerFeignClient(delegate, this.cachingFactory);
|
||||
}
|
||||
}
|
||||
}
|
||||
-94
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import com.netflix.client.ClientException;
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.DefaultClientConfigImpl;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class LoadBalancerFeignClient implements Client {
|
||||
|
||||
private final Client delegate;
|
||||
private CachingSpringLoadBalancerFactory lbClientFactory;
|
||||
|
||||
public LoadBalancerFeignClient(Client delegate, CachingSpringLoadBalancerFactory lbClientFactory) {
|
||||
this.delegate = delegate;
|
||||
this.lbClientFactory = lbClientFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
try {
|
||||
URI asUri = URI.create(request.url());
|
||||
String clientName = asUri.getHost();
|
||||
URI uriWithoutHost = cleanUrl(request.url(), clientName);
|
||||
FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(this.delegate,
|
||||
request, uriWithoutHost);
|
||||
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest,
|
||||
new FeignOptionsClientConfig(options)).toResponse();
|
||||
}
|
||||
catch (ClientException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
throw IOException.class.cast(e.getCause());
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Client getDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
static URI cleanUrl(String originalUrl, String host) {
|
||||
return URI.create(originalUrl.replaceFirst(host, ""));
|
||||
}
|
||||
|
||||
private FeignLoadBalancer lbClient(String clientName) {
|
||||
return this.lbClientFactory.create(clientName);
|
||||
}
|
||||
|
||||
static class FeignOptionsClientConfig extends DefaultClientConfigImpl {
|
||||
|
||||
public FeignOptionsClientConfig(Request.Options options) {
|
||||
setProperty(CommonClientConfigKey.ConnectTimeout,
|
||||
options.connectTimeoutMillis());
|
||||
setProperty(CommonClientConfigKey.ReadTimeout, options.readTimeoutMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadProperties(String clientName) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadDefaultValues() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
package org.springframework.cloud.netflix.feign.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import feign.FeignException;
|
||||
import feign.Response;
|
||||
import feign.codec.Decoder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Decoder adds compatibility for Spring MVC's ResponseEntity to any other decoder via
|
||||
* composition.
|
||||
* @author chadjaros
|
||||
*/
|
||||
@Slf4j
|
||||
public class ResponseEntityDecoder implements Decoder {
|
||||
|
||||
private Decoder decoder;
|
||||
|
||||
public ResponseEntityDecoder(Decoder decoder) {
|
||||
this.decoder = decoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object decode(final Response response, Type type) throws IOException,
|
||||
FeignException {
|
||||
|
||||
if (isParameterizeResponseEntity(type)) {
|
||||
type = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Object decodedObject = decoder.decode(response, type);
|
||||
|
||||
return createResponse(decodedObject, response);
|
||||
}
|
||||
else if (isResponseEntity(type)) {
|
||||
return createResponse(null, response);
|
||||
}
|
||||
else {
|
||||
return decoder.decode(response, type);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isParameterizeResponseEntity(Type type) {
|
||||
return type instanceof ParameterizedType
|
||||
&& ((ParameterizedType) type).getRawType().equals(ResponseEntity.class);
|
||||
}
|
||||
|
||||
private boolean isResponseEntity(Type type) {
|
||||
|
||||
return type instanceof Class && type.equals(ResponseEntity.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> ResponseEntity<T> createResponse(Object instance, Response response) {
|
||||
|
||||
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
||||
for (String key : response.headers().keySet()) {
|
||||
headers.put(key, new LinkedList<>(response.headers().get(key)));
|
||||
}
|
||||
|
||||
return new ResponseEntity<>((T) instance, headers, HttpStatus.valueOf(response
|
||||
.status()));
|
||||
}
|
||||
}
|
||||
-108
@@ -1,108 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.support;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.client.HttpMessageConverterExtractor;
|
||||
|
||||
import feign.FeignException;
|
||||
import feign.Response;
|
||||
import feign.codec.DecodeException;
|
||||
import feign.codec.Decoder;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringDecoder implements Decoder {
|
||||
|
||||
private ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
|
||||
public SpringDecoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||
this.messageConverters = messageConverters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object decode(final Response response, Type type) throws IOException,
|
||||
FeignException {
|
||||
if (type instanceof Class || type instanceof ParameterizedType) {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
|
||||
type, this.messageConverters.getObject().getConverters());
|
||||
|
||||
return extractor.extractData(new FeignResponseAdapter(response));
|
||||
}
|
||||
throw new DecodeException(
|
||||
"type is not an instance of Class or ParameterizedType: " + type);
|
||||
}
|
||||
|
||||
private class FeignResponseAdapter implements ClientHttpResponse {
|
||||
|
||||
private final Response response;
|
||||
|
||||
private FeignResponseAdapter(Response response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpStatus getStatusCode() throws IOException {
|
||||
return HttpStatus.valueOf(this.response.status());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawStatusCode() throws IOException {
|
||||
return this.response.status();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() throws IOException {
|
||||
return this.response.reason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
this.response.body().close();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// Ignore exception on close...
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return this.response.body().asInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(this.response.headers());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-132
@@ -1,132 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.support;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collection;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@CommonsLog
|
||||
public class SpringEncoder implements Encoder {
|
||||
|
||||
private ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
|
||||
public SpringEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||
this.messageConverters = messageConverters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(Object requestBody, Type bodyType, RequestTemplate request)
|
||||
throws EncodeException {
|
||||
// template.body(conversionService.convert(object, String.class));
|
||||
if (requestBody != null) {
|
||||
Class<?> requestType = requestBody.getClass();
|
||||
Collection<String> contentTypes = request.headers().get("Content-Type");
|
||||
|
||||
MediaType requestContentType = null;
|
||||
if (contentTypes != null && !contentTypes.isEmpty()) {
|
||||
String type = contentTypes.iterator().next();
|
||||
requestContentType = MediaType.valueOf(type);
|
||||
}
|
||||
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters
|
||||
.getObject().getConverters()) {
|
||||
if (messageConverter.canWrite(requestType, requestContentType)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
if (requestContentType != null) {
|
||||
log.debug("Writing [" + requestBody + "] as \""
|
||||
+ requestContentType + "\" using ["
|
||||
+ messageConverter + "]");
|
||||
}
|
||||
else {
|
||||
log.debug("Writing [" + requestBody + "] using ["
|
||||
+ messageConverter + "]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FeignOutputMessage outputMessage = new FeignOutputMessage(request);
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
HttpMessageConverter<Object> copy = (HttpMessageConverter<Object>) messageConverter;
|
||||
copy.write(requestBody, requestContentType, outputMessage);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new EncodeException("Error converting request body", ex);
|
||||
}
|
||||
request.body(outputMessage.getOutputStream().toByteArray(),
|
||||
Charset.forName("UTF-8")); // TODO: set charset
|
||||
return;
|
||||
}
|
||||
}
|
||||
String message = "Could not write request: no suitable HttpMessageConverter "
|
||||
+ "found for request type [" + requestType.getName() + "]";
|
||||
if (requestContentType != null) {
|
||||
message += " and content type [" + requestContentType + "]";
|
||||
}
|
||||
throw new EncodeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private class FeignOutputMessage implements HttpOutputMessage {
|
||||
|
||||
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
private final RequestTemplate request;
|
||||
|
||||
private FeignOutputMessage(RequestTemplate request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getBody() throws IOException {
|
||||
return this.outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(this.request.headers());
|
||||
}
|
||||
|
||||
public ByteArrayOutputStream getOutputStream() {
|
||||
return this.outputStream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-263
@@ -1,263 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.support;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
|
||||
import org.springframework.cloud.netflix.feign.annotation.PathVariableParameterProcessor;
|
||||
import org.springframework.cloud.netflix.feign.annotation.RequestHeaderParameterProcessor;
|
||||
import org.springframework.cloud.netflix.feign.annotation.RequestParamParameterProcessor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.MethodMetadata;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringMvcContract extends Contract.BaseContract {
|
||||
|
||||
private static final String ACCEPT = "Accept";
|
||||
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
private final Map<Class<? extends Annotation>, AnnotatedParameterProcessor> annotatedArgumentProcessors;
|
||||
|
||||
public SpringMvcContract() {
|
||||
this(Collections.<AnnotatedParameterProcessor> emptyList());
|
||||
}
|
||||
|
||||
public SpringMvcContract(
|
||||
List<AnnotatedParameterProcessor> annotatedParameterProcessors) {
|
||||
Assert.notNull(annotatedParameterProcessors,
|
||||
"Parameter processors can not be null.");
|
||||
|
||||
List<AnnotatedParameterProcessor> processors;
|
||||
if (!annotatedParameterProcessors.isEmpty()) {
|
||||
processors = new ArrayList<>(annotatedParameterProcessors);
|
||||
}
|
||||
else {
|
||||
processors = getDefaultAnnotatedArgumentsProcessors();
|
||||
}
|
||||
this.annotatedArgumentProcessors = toAnnotatedArgumentProcessorMap(processors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
|
||||
MethodMetadata md = super.parseAndValidateMetadata(targetType, method);
|
||||
|
||||
RequestMapping classAnnotation = targetType.getAnnotation(RequestMapping.class);
|
||||
if (classAnnotation != null) {
|
||||
// Prepend path from class annotation if specified
|
||||
if (classAnnotation.value().length > 0) {
|
||||
String pathValue = emptyToNull(classAnnotation.value()[0]);
|
||||
checkState(pathValue != null,
|
||||
"RequestMapping.value() was empty on type %s",
|
||||
method.getDeclaringClass().getName());
|
||||
if (!pathValue.startsWith("/")) {
|
||||
pathValue = "/" + pathValue;
|
||||
}
|
||||
md.template().insert(0, pathValue);
|
||||
}
|
||||
|
||||
// produces - use from class annotation only if method has not specified this
|
||||
if (!md.template().headers().containsKey(ACCEPT)) {
|
||||
parseProduces(md, method, classAnnotation);
|
||||
}
|
||||
|
||||
// consumes -- use from class annotation only if method has not specified this
|
||||
if (!md.template().headers().containsKey(CONTENT_TYPE)) {
|
||||
parseConsumes(md, method, classAnnotation);
|
||||
}
|
||||
|
||||
// headers -- class annotation is inherited to methods, always write these if
|
||||
// present
|
||||
parseHeaders(md, method, classAnnotation);
|
||||
}
|
||||
return md;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processAnnotationOnMethod(MethodMetadata data,
|
||||
Annotation methodAnnotation, Method method) {
|
||||
if (!(methodAnnotation instanceof RequestMapping)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RequestMapping methodMapping = RequestMapping.class.cast(methodAnnotation);
|
||||
// HTTP Method
|
||||
checkOne(method, methodMapping.method(), "method");
|
||||
data.template().method(methodMapping.method()[0].name());
|
||||
|
||||
// path
|
||||
checkAtMostOne(method, methodMapping.value(), "value");
|
||||
if (methodMapping.value().length > 0) {
|
||||
String pathValue = emptyToNull(methodMapping.value()[0]);
|
||||
if (pathValue != null) {
|
||||
// Append path from @RequestMapping if value is present on method
|
||||
if (!pathValue.startsWith("/")
|
||||
&& !data.template().toString().endsWith("/")) {
|
||||
pathValue = "/" + pathValue;
|
||||
}
|
||||
data.template().append(pathValue);
|
||||
}
|
||||
}
|
||||
|
||||
// produces
|
||||
parseProduces(data, method, methodMapping);
|
||||
|
||||
// consumes
|
||||
parseConsumes(data, method, methodMapping);
|
||||
|
||||
// headers
|
||||
parseHeaders(data, method, methodMapping);
|
||||
}
|
||||
|
||||
private void checkAtMostOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && (values.length == 0 || values.length == 1),
|
||||
"Method %s can only contain at most 1 %s field. Found: %s",
|
||||
method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
private void checkOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && values.length == 1,
|
||||
"Method %s can only contain 1 %s field. Found: %s", method.getName(),
|
||||
fieldName, values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processAnnotationsOnParameter(MethodMetadata data,
|
||||
Annotation[] annotations, int paramIndex) {
|
||||
boolean isHttpAnnotation = false;
|
||||
|
||||
AnnotatedParameterProcessor.AnnotatedParameterContext context = new SimpleAnnotatedParameterContext(
|
||||
data, paramIndex);
|
||||
for (Annotation parameterAnnotation : annotations) {
|
||||
AnnotatedParameterProcessor processor = this.annotatedArgumentProcessors
|
||||
.get(parameterAnnotation.annotationType());
|
||||
if (processor != null) {
|
||||
isHttpAnnotation |= processor.processArgument(context,
|
||||
parameterAnnotation);
|
||||
}
|
||||
}
|
||||
return isHttpAnnotation;
|
||||
}
|
||||
|
||||
private void parseProduces(MethodMetadata md, Method method,
|
||||
RequestMapping annotation) {
|
||||
checkAtMostOne(method, annotation.produces(), "produces");
|
||||
String[] serverProduces = annotation.produces();
|
||||
String clientAccepts = serverProduces.length == 0 ? null
|
||||
: emptyToNull(serverProduces[0]);
|
||||
if (clientAccepts != null) {
|
||||
md.template().header(ACCEPT, clientAccepts);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseConsumes(MethodMetadata md, Method method,
|
||||
RequestMapping annotation) {
|
||||
checkAtMostOne(method, annotation.consumes(), "consumes");
|
||||
String[] serverConsumes = annotation.consumes();
|
||||
String clientProduces = serverConsumes.length == 0 ? null
|
||||
: emptyToNull(serverConsumes[0]);
|
||||
if (clientProduces != null) {
|
||||
md.template().header(CONTENT_TYPE, clientProduces);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseHeaders(MethodMetadata md, Method method,
|
||||
RequestMapping annotation) {
|
||||
// TODO: only supports one header value per key
|
||||
if (annotation.headers() != null && annotation.headers().length > 0) {
|
||||
for (String header : annotation.headers()) {
|
||||
int colon = header.indexOf(':');
|
||||
md.template().header(header.substring(0, colon),
|
||||
header.substring(colon + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Class<? extends Annotation>, AnnotatedParameterProcessor> toAnnotatedArgumentProcessorMap(
|
||||
List<AnnotatedParameterProcessor> processors) {
|
||||
Map<Class<? extends Annotation>, AnnotatedParameterProcessor> result = new HashMap<>();
|
||||
for (AnnotatedParameterProcessor processor : processors) {
|
||||
result.put(processor.getAnnotationType(), processor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<AnnotatedParameterProcessor> getDefaultAnnotatedArgumentsProcessors() {
|
||||
|
||||
List<AnnotatedParameterProcessor> annotatedArgumentResolvers = new ArrayList<>();
|
||||
|
||||
annotatedArgumentResolvers.add(new PathVariableParameterProcessor());
|
||||
annotatedArgumentResolvers.add(new RequestParamParameterProcessor());
|
||||
annotatedArgumentResolvers.add(new RequestHeaderParameterProcessor());
|
||||
|
||||
return annotatedArgumentResolvers;
|
||||
}
|
||||
|
||||
private class SimpleAnnotatedParameterContext
|
||||
implements AnnotatedParameterProcessor.AnnotatedParameterContext {
|
||||
|
||||
private final MethodMetadata methodMetadata;
|
||||
|
||||
private final int parameterIndex;
|
||||
|
||||
public SimpleAnnotatedParameterContext(MethodMetadata methodMetadata,
|
||||
int parameterIndex) {
|
||||
this.methodMetadata = methodMetadata;
|
||||
this.parameterIndex = parameterIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodMetadata getMethodMetadata() {
|
||||
return this.methodMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParameterIndex() {
|
||||
return this.parameterIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameterName(String name) {
|
||||
nameParam(this.methodMetadata, name, this.parameterIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> setTemplateParameter(String name,
|
||||
Collection<String> rest) {
|
||||
return addTemplatedParam(rest, name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+74
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -12,50 +12,107 @@
|
||||
* 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.actuate.autoconfigure.HealthIndicatorAutoConfiguration;
|
||||
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.context.properties.ConfigurationProperties;
|
||||
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 com.netflix.hystrix.Hystrix;
|
||||
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 })
|
||||
@ConditionalOnClass({ Hystrix.class, HealthIndicator.class, HealthIndicatorAutoConfiguration.class })
|
||||
@AutoConfigureAfter({ HealthIndicatorAutoConfiguration.class })
|
||||
@ConditionalOnProperty(value = "health.hystrix.enabled", matchIfMissing = true)
|
||||
public class HystrixAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledHealthIndicator("hystrix")
|
||||
public HystrixHealthIndicator hystrixHealthIndicator() {
|
||||
return new HystrixHealthIndicator();
|
||||
}
|
||||
|
||||
@ConfigurationProperties("health.hystrix")
|
||||
public static class Health {
|
||||
/**
|
||||
* Flag to inidicate that the hystrix health indicator should be installed.
|
||||
*/
|
||||
boolean enabled;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
@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());
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-142
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -16,39 +16,20 @@
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.catalina.core.ApplicationContext;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.metrics.GaugeService;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.cloud.client.actuator.HasFeatures;
|
||||
import org.springframework.cloud.client.actuator.NamedFeature;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsAsJsonPollerListener;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Christian Dupuis
|
||||
* @author Venil Noronha
|
||||
*/
|
||||
@Configuration
|
||||
public class HystrixCircuitBreakerConfiguration {
|
||||
@@ -68,126 +49,6 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
return HasFeatures.namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "hystrix.stream.endpoint.enabled", matchIfMissing = true)
|
||||
@ConditionalOnWebApplication
|
||||
@ConditionalOnClass({ Endpoint.class, HystrixMetricsStreamServlet.class })
|
||||
protected static class HystrixWebConfiguration {
|
||||
|
||||
@Bean
|
||||
public HystrixStreamEndpoint hystrixStreamEndpoint() {
|
||||
return new HystrixStreamEndpoint();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HasFeatures hystrixFeature() {
|
||||
return HasFeatures.namedFeature("Hystrix Stream Servlet", HystrixStreamEndpoint.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass({ HystrixMetricsPoller.class, GaugeService.class })
|
||||
protected static class HystrixMetricsPollerConfiguration implements SmartLifecycle {
|
||||
|
||||
private static Log logger = LogFactory
|
||||
.getLog(HystrixMetricsPollerConfiguration.class);
|
||||
|
||||
@Autowired(required = false)
|
||||
private GaugeService gauges;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
private HystrixMetricsPoller poller;
|
||||
|
||||
private Set<String> reserved = new HashSet<String>(Arrays.asList("group", "name",
|
||||
"type", "currentTime"));
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (this.gauges == null) {
|
||||
return;
|
||||
}
|
||||
MetricsAsJsonPollerListener listener = new MetricsAsJsonPollerListener() {
|
||||
@Override
|
||||
public void handleJsonMetric(String json) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = HystrixMetricsPollerConfiguration.this.mapper
|
||||
.readValue(json, Map.class);
|
||||
if (map != null && map.containsKey("type")) {
|
||||
addMetrics(map, "hystrix.");
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
this.poller = new HystrixMetricsPoller(listener, 2000);
|
||||
// start polling and it will write directly to the listener
|
||||
this.poller.start();
|
||||
logger.info("Starting poller");
|
||||
}
|
||||
|
||||
private void addMetrics(Map<String, Object> map, String root) {
|
||||
StringBuilder prefixBuilder = new StringBuilder(root);
|
||||
if (map.containsKey("type")) {
|
||||
prefixBuilder.append((String) map.get("type"));
|
||||
if (map.containsKey("group")) {
|
||||
prefixBuilder.append(".").append(map.get("group"));
|
||||
}
|
||||
prefixBuilder.append(".").append(map.get("name"));
|
||||
}
|
||||
String prefix = prefixBuilder.toString();
|
||||
for (String key : map.keySet()) {
|
||||
Object value = map.get(key);
|
||||
if (!this.reserved.contains(key)) {
|
||||
if (value instanceof Number) {
|
||||
String name = prefix + "." + key;
|
||||
this.gauges.submit(name, ((Number) value).doubleValue());
|
||||
}
|
||||
else if (value instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> sub = (Map<String, Object>) value;
|
||||
addMetrics(sub, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (this.poller != null) {
|
||||
this.poller.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return this.poller != null ? this.poller.isRunning() : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoStartup() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(Runnable callback) {
|
||||
if (this.poller != null) {
|
||||
this.poller.shutdown();
|
||||
}
|
||||
callback.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link DisposableBean} that makes sure that Hystrix internal state is cleared when
|
||||
* {@link ApplicationContext} shuts down.
|
||||
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -19,8 +19,12 @@ package org.springframework.cloud.netflix.hystrix;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface HystrixConstants {
|
||||
public class HystrixConstants {
|
||||
|
||||
String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream";
|
||||
public static final String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream";
|
||||
|
||||
private HystrixConstants() {
|
||||
throw new AssertionError("Must not instantiate constant utility class");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ public class HystrixHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Builder builder) throws Exception {
|
||||
List<String> openCircuitBreakers = new ArrayList<String>();
|
||||
List<String> openCircuitBreakers = new ArrayList<>();
|
||||
|
||||
// Collect all open circuit breakers from Hystrix
|
||||
for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) {
|
||||
@@ -56,7 +56,7 @@ public class HystrixHealthIndicator extends AbstractHealthIndicator {
|
||||
// If there is at least one open circuit report OUT_OF_SERVICE adding the command
|
||||
// group
|
||||
// and key name
|
||||
if (openCircuitBreakers.size() > 0) {
|
||||
if (!openCircuitBreakers.isEmpty()) {
|
||||
builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers",
|
||||
openCircuitBreakers);
|
||||
}
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
+21
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* 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.
|
||||
@@ -12,29 +12,34 @@
|
||||
* 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.feign.encoding;
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* The Feign encoding properties.
|
||||
* Configuration properties for Hystrix Servlet.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
* @author Spencer Gibb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("feign.compression.request")
|
||||
public class FeignClientEncodingProperties {
|
||||
@ConfigurationProperties(prefix = "management.endpoint.hystrix")
|
||||
public class HystrixProperties {
|
||||
|
||||
/**
|
||||
* The list of supported mime types.
|
||||
*/
|
||||
private String[] mimeTypes = new String[]{"text/xml", "application/xml", "application/json"};
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum threshold content size.
|
||||
*/
|
||||
private int minRequestSize = 2048;
|
||||
}
|
||||
|
||||
+23
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -12,22 +12,36 @@
|
||||
* 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.cloud.netflix.endpoint.ServletWrappingEndpoint;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* {@link org.springframework.boot.actuate.endpoint.annotation.Endpoint} to expose a Jolokia {@link HystrixMetricsStreamServlet}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class HystrixStreamEndpoint extends ServletWrappingEndpoint {
|
||||
@ServletEndpoint(id = "hystrix.stream")
|
||||
public class HystrixStreamEndpoint implements Supplier<EndpointServlet> {
|
||||
|
||||
public HystrixStreamEndpoint() {
|
||||
super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream",
|
||||
false, true);
|
||||
}
|
||||
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
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
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
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class DefaultMetricsTagProvider implements MetricsTagProvider {
|
||||
@Override
|
||||
public Map<String, String> clientHttpRequestTags(HttpRequest request,
|
||||
ClientHttpResponse response) {
|
||||
String urlTemplate = RestTemplateUrlTemplateHolder.getRestTemplateUrlTemplate();
|
||||
if (urlTemplate == null)
|
||||
urlTemplate = "none";
|
||||
|
||||
String status;
|
||||
try {
|
||||
status = (response == null) ? "CLIENT_ERROR" : ((Integer) response
|
||||
.getRawStatusCode()).toString();
|
||||
}
|
||||
catch (IOException e) {
|
||||
status = "IO_ERROR";
|
||||
}
|
||||
|
||||
String host = request.getURI().getHost();
|
||||
|
||||
return ImmutableMap.of("method", request.getMethod().name(), "uri",
|
||||
sanitizeUrlTemplate(urlTemplate.replaceAll("^https?://[^/]+/", "")),
|
||||
"status", status, "clientName", host != null ? host : "none");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> httpRequestTags(HttpServletRequest request,
|
||||
HttpServletResponse response, Object handler, String caller) {
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
|
||||
tags.put("method", request.getMethod());
|
||||
tags.put("status", ((Integer) response.getStatus()).toString());
|
||||
|
||||
String uri = sanitizeUrlTemplate(request
|
||||
.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString()
|
||||
.substring(1));
|
||||
tags.put("uri", uri.isEmpty() ? "root" : uri);
|
||||
|
||||
Object exception = request.getAttribute("exception");
|
||||
if (exception != null)
|
||||
tags.put("exception", exception.getClass().getSimpleName());
|
||||
|
||||
if (caller != null)
|
||||
tags.put("caller", caller);
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* As is, the urlTemplate is not suitable for use with Atlas, as all interactions with
|
||||
* Atlas take place via query parameters
|
||||
*/
|
||||
private String sanitizeUrlTemplate(String urlTemplate) {
|
||||
return urlTemplate.replaceAll("/", "_").replaceAll("[{}]", "-");
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
import com.netflix.servo.MonitorRegistry;
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
import com.netflix.servo.tag.SmallTagMap;
|
||||
import com.netflix.servo.tag.Tags;
|
||||
|
||||
/**
|
||||
* Intercepts RestTemplate requests and records metrics about execution time and results.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class MetricsClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
|
||||
/**
|
||||
* The interceptor writes to a Servo MonitorRegistry, which we get away with for now
|
||||
* because our Spectator implementation is underpinned by a ServoRegistry. When Spring
|
||||
* Boot (Actuator) provides a more general purpose abstraction for dimensional metrics
|
||||
* systems, this can be moved there and rewritten against that abstraction.
|
||||
*/
|
||||
@Autowired
|
||||
MonitorRegistry registry;
|
||||
|
||||
@Autowired
|
||||
Collection<MetricsTagProvider> tagProviders;
|
||||
|
||||
@Autowired
|
||||
ServoMonitorCache servoMonitorCache;
|
||||
|
||||
@Value("${netflix.metrics.restClient.metricName:restclient}")
|
||||
String metricName;
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
|
||||
ClientHttpRequestExecution execution) throws IOException {
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
ClientHttpResponse response = null;
|
||||
try {
|
||||
response = execution.execute(request, body);
|
||||
return response;
|
||||
}
|
||||
finally {
|
||||
SmallTagMap.Builder builder = SmallTagMap.builder();
|
||||
for (MetricsTagProvider tagProvider : tagProviders) {
|
||||
for (Map.Entry<String, String> tag : tagProvider.clientHttpRequestTags(
|
||||
request, response).entrySet()) {
|
||||
builder.add(Tags.newTag(tag.getKey(), tag.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
MonitorConfig.Builder monitorConfigBuilder = MonitorConfig
|
||||
.builder(metricName);
|
||||
monitorConfigBuilder.withTags(builder);
|
||||
|
||||
servoMonitorCache.getTimer(monitorConfigBuilder.build()).record(
|
||||
System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
-98
@@ -1,98 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import com.netflix.servo.MonitorRegistry;
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
import com.netflix.servo.tag.SmallTagMap;
|
||||
import com.netflix.servo.tag.Tags;
|
||||
|
||||
import static org.springframework.web.context.request.RequestAttributes.SCOPE_REQUEST;
|
||||
|
||||
/**
|
||||
* Intercepts incoming HTTP requests and records metrics about execution time and results.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class MetricsHandlerInterceptor extends HandlerInterceptorAdapter {
|
||||
@Value("${netflix.metrics.rest.metricName:rest}")
|
||||
String metricName;
|
||||
|
||||
@Value("${netflix.metrics.rest.callerHeader:#{null}}")
|
||||
String callerHeader;
|
||||
|
||||
@Autowired
|
||||
MonitorRegistry registry;
|
||||
|
||||
@Autowired
|
||||
ServoMonitorCache servoMonitorCache;
|
||||
|
||||
@Autowired
|
||||
Collection<MetricsTagProvider> tagProviders;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler) throws Exception {
|
||||
RequestContextHolder.getRequestAttributes().setAttribute("requestStartTime",
|
||||
System.nanoTime(), SCOPE_REQUEST);
|
||||
return super.preHandle(request, response, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler, Exception ex) throws Exception {
|
||||
RequestContextHolder.getRequestAttributes().setAttribute("exception", ex,
|
||||
SCOPE_REQUEST);
|
||||
Long startTime = (Long) RequestContextHolder.getRequestAttributes().getAttribute(
|
||||
"requestStartTime", SCOPE_REQUEST);
|
||||
if (startTime != null)
|
||||
recordMetric(request, response, handler, startTime);
|
||||
super.afterCompletion(request, response, handler, ex);
|
||||
}
|
||||
|
||||
protected void recordMetric(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler, Long startTime) {
|
||||
String caller = null;
|
||||
if (callerHeader != null) {
|
||||
caller = request.getHeader(callerHeader);
|
||||
}
|
||||
|
||||
SmallTagMap.Builder builder = SmallTagMap.builder();
|
||||
for (MetricsTagProvider tagProvider : tagProviders) {
|
||||
Map<String, String> tags = tagProvider.httpRequestTags(request, response,
|
||||
handler, caller);
|
||||
for (Map.Entry<String, String> tag : tags.entrySet()) {
|
||||
builder.add(Tags.newTag(tag.getKey(), tag.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
MonitorConfig.Builder monitorConfigBuilder = MonitorConfig.builder(metricName);
|
||||
monitorConfigBuilder.withTags(builder);
|
||||
|
||||
servoMonitorCache.getTimer(monitorConfigBuilder.build()).record(
|
||||
System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
|
||||
}
|
||||
}
|
||||
-95
@@ -1,95 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
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.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
import com.netflix.servo.monitor.Monitors;
|
||||
|
||||
/**
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Monitors.class, MetricReader.class })
|
||||
public class MetricsInterceptorConfiguration {
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication
|
||||
static class MetricsWebResourceConfiguration extends WebMvcConfigurerAdapter {
|
||||
@Bean
|
||||
MetricsHandlerInterceptor servoMonitoringWebResourceInterceptor() {
|
||||
return new MetricsHandlerInterceptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(servoMonitoringWebResourceInterceptor());
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(JoinPoint.class)
|
||||
@ConditionalOnProperty(value = "spring.aop.enabled", havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnBean({ RestTemplate.class })
|
||||
static class MetricsRestTemplateAspectConfiguration {
|
||||
|
||||
@Bean
|
||||
RestTemplateUrlTemplateCapturingAspect restTemplateUrlTemplateCapturingAspect() {
|
||||
return new RestTemplateUrlTemplateCapturingAspect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean({ RestTemplate.class })
|
||||
static class MetricsRestTemplateConfiguration {
|
||||
|
||||
@Bean
|
||||
MetricsClientHttpRequestInterceptor spectatorLoggingClientHttpRequestInterceptor() {
|
||||
return new MetricsClientHttpRequestInterceptor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
BeanPostProcessor spectatorRestTemplateInterceptorPostProcessor(
|
||||
final MetricsClientHttpRequestInterceptor interceptor) {
|
||||
return new BeanPostProcessor() {
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean,
|
||||
String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean,
|
||||
String beanName) {
|
||||
if (bean instanceof RestTemplate) {
|
||||
((RestTemplate) bean).getInterceptors().add(interceptor);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
-43
@@ -1,43 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
/**
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public interface MetricsTagProvider {
|
||||
/**
|
||||
* @param request RestTemplate client HTTP request
|
||||
* @param response may be null in the event of a client error
|
||||
* @return a map of tags added to every client HTTP request metric
|
||||
*/
|
||||
Map<String, String> clientHttpRequestTags(HttpRequest request,
|
||||
ClientHttpResponse response);
|
||||
|
||||
/**
|
||||
* @param request HTTP request
|
||||
* @param response HTTP response
|
||||
* @param handler the request method that is responsible for handling the request
|
||||
* @return a map of tags added to every Spring MVC HTTP request metric
|
||||
*/
|
||||
Map<String, String> httpRequestTags(HttpServletRequest request,
|
||||
HttpServletResponse response, Object handler, String caller);
|
||||
}
|
||||
-39
@@ -1,39 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
/**
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class MetricsTagProviderAdapter implements MetricsTagProvider {
|
||||
@Override
|
||||
public Map<String, String> clientHttpRequestTags(HttpRequest request,
|
||||
ClientHttpResponse response) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> httpRequestTags(HttpServletRequest request,
|
||||
HttpServletResponse response, Object handler, String caller) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
-39
@@ -1,39 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
|
||||
/**
|
||||
* Captures the still-templated URI because currently the ClientHttpRequestInterceptor
|
||||
* currently only gives us the means to retrieve the substituted URI.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
@Aspect
|
||||
public class RestTemplateUrlTemplateCapturingAspect {
|
||||
@Around("execution(* org.springframework.web.client.RestOperations+.*(String, ..))")
|
||||
Object captureUrlTemplate(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
try {
|
||||
String urlTemplate = (String) joinPoint.getArgs()[0];
|
||||
RestTemplateUrlTemplateHolder.setRestTemplateUrlTemplate(urlTemplate);
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
finally {
|
||||
RestTemplateUrlTemplateHolder.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
-39
@@ -1,39 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics;
|
||||
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
|
||||
/**
|
||||
* Holding area for the still-templated URI because currently the
|
||||
* ClientHttpRequestInterceptor only gives us the means to retrieve the substituted URI.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class RestTemplateUrlTemplateHolder {
|
||||
private static final ThreadLocal<String> restTemplateUrlTemplateHolder = new NamedThreadLocal<String>(
|
||||
"Rest Template URL Template");
|
||||
|
||||
public static String getRestTemplateUrlTemplate() {
|
||||
return restTemplateUrlTemplateHolder.get();
|
||||
}
|
||||
|
||||
public static void setRestTemplateUrlTemplate(String urlTemplate) {
|
||||
restTemplateUrlTemplateHolder.set(urlTemplate);
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
restTemplateUrlTemplateHolder.remove();
|
||||
}
|
||||
}
|
||||
-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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.atlas;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.metrics.export.Exporter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.netflix.metrics.servo.ServoMetricsAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.netflix.servo.MonitorRegistry;
|
||||
import com.netflix.servo.publish.MonitorRegistryMetricPoller;
|
||||
import com.netflix.servo.tag.BasicTagList;
|
||||
|
||||
/**
|
||||
* Configures the Atlas metrics backend, also configuring Spectator to collect metrics if necessary.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(AtlasMetricObserver.class)
|
||||
@Import(ServoMetricsAutoConfiguration.class)
|
||||
public class AtlasAutoConfiguration {
|
||||
@Autowired(required = false)
|
||||
private Collection<AtlasTagProvider> tagProviders;
|
||||
|
||||
@Bean
|
||||
public AtlasMetricObserverConfigBean atlasObserverConfig() {
|
||||
return new AtlasMetricObserverConfigBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AtlasMetricObserver atlasObserver(AtlasMetricObserverConfigBean atlasObserverConfig, RestTemplate restTemplate) {
|
||||
BasicTagList tags = (BasicTagList) BasicTagList.EMPTY;
|
||||
if (tagProviders != null) {
|
||||
for (AtlasTagProvider tagProvider : tagProviders) {
|
||||
for (Map.Entry<String, String> tag : tagProvider.defaultTags().entrySet()) {
|
||||
if (tag.getValue() != null)
|
||||
tags = tags.copy(tag.getKey(), tag.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new AtlasMetricObserver(atlasObserverConfig, restTemplate, tags);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Exporter exporter(AtlasMetricObserver observer, MonitorRegistry monitorRegistry) {
|
||||
return new AtlasExporter(observer, new MonitorRegistryMetricPoller(monitorRegistry));
|
||||
}
|
||||
}
|
||||
-37
@@ -1,37 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.atlas;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.export.Exporter;
|
||||
|
||||
import com.netflix.servo.publish.BasicMetricFilter;
|
||||
import com.netflix.servo.publish.MetricPoller;
|
||||
|
||||
/**
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class AtlasExporter implements Exporter {
|
||||
private AtlasMetricObserver observer;
|
||||
private MetricPoller poller;
|
||||
|
||||
public AtlasExporter(AtlasMetricObserver observer, MetricPoller poller) {
|
||||
this.observer = observer;
|
||||
this.poller = poller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export() {
|
||||
observer.update(poller.poll(BasicMetricFilter.MATCH_ALL));
|
||||
}
|
||||
}
|
||||
-241
@@ -1,241 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.atlas;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonEncoding;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
|
||||
import com.netflix.servo.Metric;
|
||||
import com.netflix.servo.annotations.DataSourceType;
|
||||
import com.netflix.servo.publish.MetricObserver;
|
||||
import com.netflix.servo.tag.BasicTag;
|
||||
import com.netflix.servo.tag.Tag;
|
||||
import com.netflix.servo.tag.TagList;
|
||||
|
||||
/**
|
||||
* Observer that forwards metrics to atlas. In addition to being a MetricObserver, it also
|
||||
* supports a push model that sends metrics as soon as possible (asynchronously).
|
||||
*
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class AtlasMetricObserver implements MetricObserver {
|
||||
private static final Log logger = LogFactory.getLog(AtlasMetricObserver.class);
|
||||
private static final SmileFactory smileFactory = new SmileFactory();
|
||||
private static final Tag atlasRateTag = new BasicTag("atlas.dstype", "rate");
|
||||
private static final Tag atlasCounterTag = new BasicTag("atlas.dstype", "counter");
|
||||
private static final Tag atlasGaugeTag = new BasicTag("atlas.dstype", "gauge");
|
||||
private static final Pattern validAtlasTag = Pattern.compile("[\\.\\-\\w]+");
|
||||
|
||||
private AtlasMetricObserverConfigBean config;
|
||||
private RestTemplate restTemplate;
|
||||
private TagList commonTags;
|
||||
private String uri;
|
||||
|
||||
public AtlasMetricObserver(AtlasMetricObserverConfigBean config,
|
||||
RestTemplate restTemplate, TagList commonTags) {
|
||||
this.config = config;
|
||||
this.commonTags = commonTags;
|
||||
this.restTemplate = restTemplate;
|
||||
this.uri = normalizeAtlasUri(config.getUri());
|
||||
|
||||
if (!validTags(commonTags)) {
|
||||
throw new IllegalArgumentException(
|
||||
"One or more atlas tags contain invalid characters, must match [\\.\\-\\w]+");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "atlas";
|
||||
}
|
||||
|
||||
protected static boolean validTags(TagList tags) {
|
||||
for (Tag tag : tags) {
|
||||
if (!validAtlasTag.matcher(tag.getKey()).matches()) {
|
||||
logger.debug("Invalid tag key " + tag.getKey());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!validAtlasTag.matcher(tag.getValue()).matches()) {
|
||||
logger.debug("Invalid tag value " + tag.getValue());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static String normalizeAtlasUri(String uri) {
|
||||
if (uri != null) {
|
||||
Matcher matcher = Pattern.compile("(.+?)(/api/v1/publish)?/?").matcher(uri);
|
||||
if (matcher.matches())
|
||||
return matcher.group(1) + "/api/v1/publish";
|
||||
else
|
||||
throw new IllegalStateException("netflix.atlas.uri is not a valid uri");
|
||||
}
|
||||
throw new IllegalStateException("netflix.atlas.uri was not found in your properties and is required to communicate with Atlas");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(List<Metric> rawMetrics) {
|
||||
if (!config.isEnabled()) {
|
||||
logger.debug("Atlas metric observer disabled. Not sending metrics.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rawMetrics.isEmpty()) {
|
||||
logger.debug("Metrics list is empty, no data being sent to server.");
|
||||
return;
|
||||
}
|
||||
|
||||
List<Metric> metrics = addTypeTagsAsNecessary(rawMetrics);
|
||||
|
||||
for (int i = 0; i < metrics.size(); i += config.getBatchSize()) {
|
||||
List<Metric> batch = metrics.subList(i,
|
||||
Math.min(metrics.size(), config.getBatchSize() + i));
|
||||
logger.debug("Sending a metrics batch of size " + batch.size());
|
||||
sendMetricsBatch(batch);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMetricsBatch(List<Metric> metrics) {
|
||||
try {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
JsonGenerator gen = smileFactory.createGenerator(output, JsonEncoding.UTF8);
|
||||
|
||||
gen.writeStartObject();
|
||||
|
||||
writeCommonTags(gen);
|
||||
if (writeMetrics(gen, metrics) == 0)
|
||||
return; // short circuit this batch if no valid/numeric metrics existed
|
||||
|
||||
gen.writeEndObject();
|
||||
gen.flush();
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.valueOf("application/x-jackson-smile"));
|
||||
HttpEntity<byte[]> entity = new HttpEntity<>(output.toByteArray(), headers);
|
||||
try {
|
||||
restTemplate.exchange(uri, HttpMethod.POST, entity, Map.class);
|
||||
}
|
||||
catch (HttpClientErrorException e) {
|
||||
logger.error(
|
||||
"Failed to write metrics to atlas: "
|
||||
+ e.getResponseBodyAsString(), e);
|
||||
}
|
||||
catch (RestClientException e) {
|
||||
logger.error("Failed to write metrics to atlas", e);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
// an IOException stemming from the generator writing to a
|
||||
// ByteArrayOutputStream is impossible
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeCommonTags(JsonGenerator gen) throws IOException {
|
||||
gen.writeObjectFieldStart("tags");
|
||||
for (Tag tag : commonTags)
|
||||
gen.writeStringField(tag.getKey(), tag.getValue());
|
||||
gen.writeEndObject();
|
||||
}
|
||||
|
||||
private int writeMetrics(JsonGenerator gen, List<Metric> metrics) throws IOException {
|
||||
int totalMetricsInBatch = 0;
|
||||
gen.writeArrayFieldStart("metrics");
|
||||
|
||||
for (Metric m : metrics) {
|
||||
if (!validTags(m.getConfig().getTags()))
|
||||
continue;
|
||||
|
||||
if (!Number.class.isAssignableFrom(m.getValue().getClass()))
|
||||
continue;
|
||||
|
||||
gen.writeStartObject();
|
||||
|
||||
gen.writeObjectFieldStart("tags");
|
||||
gen.writeStringField("name", m.getConfig().getName());
|
||||
for (Tag tag : m.getConfig().getTags())
|
||||
gen.writeStringField(tag.getKey(), tag.getValue());
|
||||
gen.writeEndObject();
|
||||
|
||||
gen.writeNumberField("start", m.getTimestamp());
|
||||
gen.writeNumberField("value", m.getNumberValue().doubleValue());
|
||||
|
||||
gen.writeEndObject();
|
||||
|
||||
totalMetricsInBatch++;
|
||||
}
|
||||
|
||||
gen.writeEndArray();
|
||||
return totalMetricsInBatch;
|
||||
}
|
||||
|
||||
protected static List<Metric> addTypeTagsAsNecessary(List<Metric> metrics) {
|
||||
List<Metric> typedMetrics = new ArrayList<>();
|
||||
for (Metric m : metrics) {
|
||||
String value = m.getConfig().getTags().getValue(DataSourceType.KEY);
|
||||
Metric transformed;
|
||||
|
||||
// Atlas will not normalize metrics tagged with atlas.dstype=gauge. Since
|
||||
// these metric types are
|
||||
// pre-normalized, we do not want Atlas to touch the value
|
||||
if (DataSourceType.GAUGE.name().equals(value)
|
||||
|| DataSourceType.RATE.name().equals(value)
|
||||
|| DataSourceType.NORMALIZED.name().equals(value)) {
|
||||
transformed = new Metric(m.getConfig().withAdditionalTag(atlasGaugeTag),
|
||||
m.getTimestamp(), m.getValue());
|
||||
}
|
||||
|
||||
// atlas.dstype=counter means you're sending the absolute value of the counter
|
||||
// (a monotonically
|
||||
// increasing value), and Atlas will keep the previous value and convert it to
|
||||
// a rate per second
|
||||
// when the metric is received
|
||||
else if (DataSourceType.COUNTER.name().equals(value)) {
|
||||
transformed = new Metric(
|
||||
m.getConfig().withAdditionalTag(atlasCounterTag),
|
||||
m.getTimestamp(), m.getValue());
|
||||
}
|
||||
|
||||
// Atlas will normalize the value to a minute boundary based on its timestamp
|
||||
else {
|
||||
transformed = new Metric(m.getConfig().withAdditionalTag(atlasRateTag),
|
||||
m.getTimestamp(), m.getValue());
|
||||
}
|
||||
|
||||
typedMetrics.add(transformed);
|
||||
}
|
||||
return typedMetrics;
|
||||
}
|
||||
}
|
||||
-50
@@ -1,50 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.atlas;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
@ConfigurationProperties("netflix.atlas")
|
||||
public class AtlasMetricObserverConfigBean {
|
||||
private String uri;
|
||||
private boolean enabled = true;
|
||||
private Integer batchSize = 10000;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public int getBatchSize() {
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setBatchSize(Integer batchSize) {
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
}
|
||||
-26
@@ -1,26 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.atlas;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provide implementations of this interface in your application context to add a set of static tags to every metric
|
||||
* sent to Atlas.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public interface AtlasTagProvider {
|
||||
Map<String, String> defaultTags();
|
||||
}
|
||||
-34
@@ -1,34 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.atlas;
|
||||
|
||||
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.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Annotation for clients to enable Atlas metrics publishing.
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@Import(AtlasAutoConfiguration.class)
|
||||
public @interface EnableAtlas {
|
||||
}
|
||||
-38
@@ -1,38 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.servo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.netflix.servo.monitor.Monitor;
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
import com.netflix.servo.tag.Tag;
|
||||
|
||||
/**
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class DimensionalServoMetricNaming implements ServoMetricNaming {
|
||||
@Override
|
||||
public String asHierarchicalName(Monitor<?> monitor) {
|
||||
MonitorConfig config = monitor.getConfig();
|
||||
List<String> tags = new ArrayList<>(config.getTags().size());
|
||||
for (Tag t : config.getTags()) {
|
||||
tags.add(t.getKey() + "=" + t.getValue());
|
||||
}
|
||||
return config.getName() + "(" + StringUtils.join(tags, ",") + ")";
|
||||
}
|
||||
}
|
||||
-110
@@ -1,110 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.servo;
|
||||
|
||||
import com.netflix.servo.annotations.DataSourceType;
|
||||
import com.netflix.servo.monitor.Monitor;
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
import com.netflix.servo.tag.Tag;
|
||||
import com.netflix.servo.tag.TagList;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class HierarchicalServoMetricNaming implements ServoMetricNaming {
|
||||
private static final String JMX_DOMAIN_KEY = "JmxDomain";
|
||||
public static final String SERVO = "servo.";
|
||||
|
||||
@Override
|
||||
public String asHierarchicalName(Monitor<?> monitor) {
|
||||
MonitorConfig config = monitor.getConfig();
|
||||
TagList tags = config.getTags();
|
||||
|
||||
Tag domainTag = tags.getTag(JMX_DOMAIN_KEY);
|
||||
String name;
|
||||
if (domainTag != null) { // jmx metric
|
||||
name = handleJmxMetric(config, tags);
|
||||
} else {
|
||||
name = handleMetric(config, tags);
|
||||
}
|
||||
return name.toLowerCase();
|
||||
}
|
||||
|
||||
private String handleMetric(MonitorConfig config, TagList tags) {
|
||||
String type = cleanValue(tags.getTag(DataSourceType.KEY), false);
|
||||
String instanceName = cleanValue(tags.getTag("instance"), false);
|
||||
String name = cleanupIllegalCharacters(config.getName(), true);
|
||||
String statistic = cleanValue(tags.getTag("statistic"), false);
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
if (type != null) {
|
||||
nameBuilder.append(type).append(".");
|
||||
}
|
||||
nameBuilder.append(SERVO);
|
||||
if (instanceName != null) {
|
||||
nameBuilder.append(instanceName).append(".");
|
||||
}
|
||||
if (name != null) {
|
||||
nameBuilder.append(name).append(".");
|
||||
}
|
||||
if (statistic != null) {
|
||||
nameBuilder.append(statistic).append(".");
|
||||
}
|
||||
// remove trailing "."
|
||||
nameBuilder.deleteCharAt(nameBuilder.lastIndexOf("."));
|
||||
return nameBuilder.toString();
|
||||
}
|
||||
|
||||
private String handleJmxMetric(MonitorConfig config, TagList tags) {
|
||||
String domain = cleanValue(tags.getTag(JMX_DOMAIN_KEY), true);
|
||||
String type = cleanValue(tags.getTag("Jmx.type"), false);
|
||||
String instanceName = cleanValue(tags.getTag("Jmx.instance"), false);
|
||||
String name = cleanValue(tags.getTag("Jmx.name"), true);
|
||||
String fieldName = cleanupIllegalCharacters(config.getName(), false);
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
nameBuilder.append(domain).append(".");
|
||||
if (type != null) {
|
||||
nameBuilder.append(type).append(".");
|
||||
}
|
||||
nameBuilder.append(SERVO);
|
||||
if (instanceName != null) {
|
||||
nameBuilder.append(instanceName).append(".");
|
||||
}
|
||||
if (name != null) {
|
||||
nameBuilder.append(name).append(".");
|
||||
}
|
||||
if (fieldName != null) {
|
||||
nameBuilder.append(fieldName).append(".");
|
||||
}
|
||||
// remove trailing "."
|
||||
nameBuilder.deleteCharAt(nameBuilder.lastIndexOf("."));
|
||||
return nameBuilder.toString();
|
||||
}
|
||||
|
||||
private String cleanValue(Tag tag, boolean allowPeriodsInName) {
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return cleanupIllegalCharacters(tag.getValue(), allowPeriodsInName);
|
||||
}
|
||||
|
||||
private String cleanupIllegalCharacters(String s, boolean allowPeriodsInName) {
|
||||
if (!allowPeriodsInName) {
|
||||
s = s.replace(".", "_");
|
||||
}
|
||||
return s.replace(" ", "_");
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.servo;
|
||||
|
||||
import com.netflix.servo.monitor.Monitor;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface ServoMetricNaming {
|
||||
/**
|
||||
* @param monitor a monitor representing a single statistic (not a CompositeMonitor)
|
||||
* @return a hierarchical name representing a single statistic for a servo monitor;
|
||||
* note that this method will be called once for each statistic on a composite servo
|
||||
* Monitor like a Timer.
|
||||
*/
|
||||
String asHierarchicalName(Monitor<?> monitor);
|
||||
}
|
||||
-87
@@ -1,87 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.servo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
|
||||
import com.netflix.servo.MonitorRegistry;
|
||||
import com.netflix.servo.monitor.CompositeMonitor;
|
||||
import com.netflix.servo.monitor.Monitor;
|
||||
|
||||
/**
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class ServoMetricReader implements MetricReader {
|
||||
MonitorRegistry monitorRegistry;
|
||||
ServoMetricNaming metricNaming;
|
||||
|
||||
public ServoMetricReader(MonitorRegistry monitorRegistry,
|
||||
ServoMetricNaming metricNaming) {
|
||||
this.monitorRegistry = monitorRegistry;
|
||||
this.metricNaming = metricNaming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metric<?> findOne(String s) {
|
||||
throw new UnsupportedOperationException(
|
||||
"cannot construct a tag-based Servo id from a hierarchical name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Metric<?>> findAll() {
|
||||
Collection<Metric<?>> metrics = new ArrayList<>();
|
||||
for (Monitor<?> monitor : monitorRegistry.getRegisteredMonitors()) {
|
||||
addToMetrics(monitor, metrics);
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
|
||||
private void addToMetrics(Monitor<?> monitor, Collection<Metric<?>> metrics) {
|
||||
if (monitor instanceof CompositeMonitor) {
|
||||
for (Monitor<?> nestedMonitor : ((CompositeMonitor<?>) monitor).getMonitors()) {
|
||||
addToMetrics(nestedMonitor, metrics);
|
||||
}
|
||||
}
|
||||
else if (monitor.getValue() instanceof Number) {
|
||||
// Servo does support non-numeric values, but there is no such concept in
|
||||
// Spring Boot
|
||||
metrics.add(new Metric<>(metricNaming.asHierarchicalName(monitor),
|
||||
(Number) monitor.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
long count = 0;
|
||||
for (Monitor<?> monitor : monitorRegistry.getRegisteredMonitors()) {
|
||||
count += countMetrics(monitor);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private static long countMetrics(Monitor<?> monitor) {
|
||||
if (monitor instanceof CompositeMonitor) {
|
||||
long count = 0;
|
||||
for (Monitor<?> nestedMonitor : ((CompositeMonitor<?>) monitor).getMonitors()) {
|
||||
count += countMetrics(nestedMonitor);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
-145
@@ -1,145 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.servo;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.CounterService;
|
||||
import org.springframework.boot.actuate.metrics.GaugeService;
|
||||
|
||||
import com.netflix.servo.MonitorRegistry;
|
||||
import com.netflix.servo.monitor.BasicCounter;
|
||||
import com.netflix.servo.monitor.BasicDistributionSummary;
|
||||
import com.netflix.servo.monitor.BasicTimer;
|
||||
import com.netflix.servo.monitor.DoubleGauge;
|
||||
import com.netflix.servo.monitor.LongGauge;
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
|
||||
/**
|
||||
* Provides a <code>CounterService</code> and <code>GaugeService</code> implementation
|
||||
* backed by Servo.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
public class ServoMetricServices implements CounterService, GaugeService {
|
||||
private final MonitorRegistry registry;
|
||||
|
||||
private final ConcurrentMap<String, BasicCounter> counters = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, LongGauge> longGauges = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, DoubleGauge> doubleGauges = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, BasicDistributionSummary> distributionSummaries = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, BasicTimer> timers = new ConcurrentHashMap<>();
|
||||
|
||||
public ServoMetricServices(MonitorRegistry registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
protected static String stripMetricName(String metricName) {
|
||||
return metricName.replaceFirst("^(timer|histogram|meter)\\.", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment(String name) {
|
||||
incrementInternal(name, 1L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrement(String name) {
|
||||
incrementInternal(name, -1L);
|
||||
}
|
||||
|
||||
private void incrementInternal(String name, long value) {
|
||||
String strippedName = stripMetricName(name);
|
||||
|
||||
if (name.startsWith("status.")) {
|
||||
// drop this metric since we are capturing it already with
|
||||
// ServoHandlerInterceptor,
|
||||
// and we are able to glean more information like exceptionType from that
|
||||
// mechanism than what
|
||||
// boot provides us
|
||||
}
|
||||
else if (name.startsWith("meter.")) {
|
||||
BasicCounter counter = counters.get(strippedName);
|
||||
if (counter == null) {
|
||||
counter = new BasicCounter(MonitorConfig.builder(strippedName).build());
|
||||
counters.put(strippedName, counter);
|
||||
registry.register(counter);
|
||||
}
|
||||
counter.increment(value);
|
||||
}
|
||||
else {
|
||||
LongGauge gauge = longGauges.get(strippedName);
|
||||
if (gauge == null) {
|
||||
gauge = new LongGauge(MonitorConfig.builder(strippedName).build());
|
||||
longGauges.put(strippedName, gauge);
|
||||
registry.register(gauge);
|
||||
}
|
||||
gauge.set(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(String name) {
|
||||
String strippedName = stripMetricName(name);
|
||||
BasicCounter counter = counters.remove(strippedName);
|
||||
if (counter != null)
|
||||
registry.unregister(counter);
|
||||
|
||||
LongGauge gauge = longGauges.remove(strippedName);
|
||||
if (gauge != null)
|
||||
registry.unregister(gauge);
|
||||
|
||||
BasicDistributionSummary distributionSummary = distributionSummaries
|
||||
.remove(strippedName);
|
||||
if (distributionSummary != null)
|
||||
registry.unregister(distributionSummary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submit(String name, double dValue) {
|
||||
long value = ((Double) dValue).longValue();
|
||||
String strippedName = stripMetricName(name);
|
||||
if (name.startsWith("histogram.")) {
|
||||
BasicDistributionSummary distributionSummary = distributionSummaries
|
||||
.get(strippedName);
|
||||
if (distributionSummary == null) {
|
||||
distributionSummary = new BasicDistributionSummary(MonitorConfig.builder(
|
||||
strippedName).build());
|
||||
distributionSummaries.put(strippedName, distributionSummary);
|
||||
registry.register(distributionSummary);
|
||||
}
|
||||
distributionSummary.record(value);
|
||||
}
|
||||
else if (name.startsWith("timer.")) {
|
||||
BasicTimer timer = timers.get(strippedName);
|
||||
if (timer == null) {
|
||||
timer = new BasicTimer(MonitorConfig.builder(strippedName).build());
|
||||
timers.put(strippedName, timer);
|
||||
registry.register(timer);
|
||||
}
|
||||
timer.record(value, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
else {
|
||||
DoubleGauge gauge = doubleGauges.get(strippedName);
|
||||
if (gauge == null) {
|
||||
gauge = new DoubleGauge(MonitorConfig.builder(strippedName).build());
|
||||
doubleGauges.put(strippedName, gauge);
|
||||
registry.register(gauge);
|
||||
}
|
||||
gauge.set(dValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
-87
@@ -1,87 +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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.metrics.servo;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.MetricRepositoryAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.MetricReaderPublicMetrics;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.cloud.netflix.metrics.DefaultMetricsTagProvider;
|
||||
import org.springframework.cloud.netflix.metrics.MetricsInterceptorConfiguration;
|
||||
import org.springframework.cloud.netflix.metrics.MetricsTagProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import com.netflix.servo.DefaultMonitorRegistry;
|
||||
import com.netflix.servo.MonitorRegistry;
|
||||
import com.netflix.servo.monitor.Monitors;
|
||||
|
||||
/**
|
||||
* Auto configuration to configure Servo support.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Christian Dupuis
|
||||
* @author Jon Schneider
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Monitors.class, MetricReader.class })
|
||||
@ConditionalOnMissingClass("com.netflix.spectator.api.Registry")
|
||||
@AutoConfigureBefore(MetricRepositoryAutoConfiguration.class)
|
||||
@Import(MetricsInterceptorConfiguration.class)
|
||||
public class ServoMetricsAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServoMetricsConfigBean servoMetricsConfig() {
|
||||
return new ServoMetricsConfigBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServoMetricNaming servoMetricNaming() {
|
||||
return new HierarchicalServoMetricNaming();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public MonitorRegistry monitorRegistry(ServoMetricsConfigBean servoMetricsConfig) {
|
||||
System.setProperty(DefaultMonitorRegistry.class.getCanonicalName() + ".registryClass", servoMetricsConfig
|
||||
.getRegistryClass());
|
||||
return DefaultMonitorRegistry.getInstance();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServoMonitorCache monitorCache(MonitorRegistry monitorRegistry) {
|
||||
return new ServoMonitorCache(monitorRegistry);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MetricReaderPublicMetrics servoPublicMetrics(MonitorRegistry monitorRegistry, ServoMetricNaming servoMetricNaming) {
|
||||
ServoMetricReader reader = new ServoMetricReader(monitorRegistry, servoMetricNaming);
|
||||
return new MetricReaderPublicMetrics(reader);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServoMetricServices servoMetricServices(MonitorRegistry monitorRegistry) {
|
||||
return new ServoMetricServices(monitorRegistry);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MetricsTagProvider defaultMetricsTagProvider() {
|
||||
return new DefaultMetricsTagProvider();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user