diff --git a/.circleci/config.yml b/.circleci/config.yml index b1811623..0904aef7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ jobs: build: docker: - image: springcloud/pipeline-base -# user: appuser + # user: appuser environment: _JAVA_OPTIONS: "-Xms1024m -Xmx2048m" TERM: dumb @@ -43,4 +43,4 @@ jobs: destination: artifacts - store_test_results: path: ~/junit/ - destination: testartifacts \ No newline at end of file + destination: testartifacts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..0e33fa5c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = tab +indent_size = 4 +end_of_line = lf +insert_final_newline = true + +[*.yml] +indent_style = space +indent_size = 2 + +[*.yaml] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index d97cb9e8..861e8a80 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ _site/ .factorypath *.swp /consul -consul_*.zip \ No newline at end of file +consul_*.zip +consul_*.zip.* diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 00000000..f3e6046f --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ + +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + 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. +*/ + +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is + * provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl + * property to use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for + * the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a + // custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, + MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream( + mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } + catch (IOException e) { + System.out.println( + "- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } + finally { + try { + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } + catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), + MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println("- ERROR creating output direcrory '" + + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } + catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) + throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar old mode 100644 new mode 100755 index 5fd4d502..01e67997 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties old mode 100644 new mode 100755 index 56bb0164..00d32aab --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip \ No newline at end of file +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip \ No newline at end of file diff --git a/.settings.xml b/.settings.xml index 270181b3..514b7e0e 100644 --- a/.settings.xml +++ b/.settings.xml @@ -10,7 +10,9 @@ spring - true + + true + spring-snapshots diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulLifecycle.java b/.springformat similarity index 100% rename from spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulLifecycle.java rename to .springformat diff --git a/asciidoctor.css b/asciidoctor.css index 06d52e68..ee4f1d81 100644 --- a/asciidoctor.css +++ b/asciidoctor.css @@ -1,399 +1,2011 @@ /* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */ /* Remove the comments around the @import statement below when using this as a custom stylesheet */ /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic|Noto+Serif:400,400italic,700,700italic|Droid+Sans+Mono:400";*/ -article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block} -audio,canvas,video{display:inline-block} -audio:not([controls]){display:none;height:0} -[hidden],template{display:none} -script{display:none!important} -html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} -body{margin:0} -a{background:transparent} -a:focus{outline:thin dotted} -a:active,a:hover{outline:0} -h1{font-size:2em;margin:.67em 0} -abbr[title]{border-bottom:1px dotted} -b,strong{font-weight:bold} -dfn{font-style:italic} -hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0} -mark{background:#ff0;color:#000} -code,kbd,pre,samp{font-family:monospace;font-size:1em} -pre{white-space:pre-wrap} -q{quotes:"\201C" "\201D" "\2018" "\2019"} -small{font-size:80%} -sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} -sup{top:-.5em} -sub{bottom:-.25em} -img{border:0} -svg:not(:root){overflow:hidden} -figure{margin:0} -fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} -legend{border:0;padding:0} -button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} -button,input{line-height:normal} -button,select{text-transform:none} -button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} -button[disabled],html input[disabled]{cursor:default} -input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0} -input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box} -input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none} -button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} -textarea{overflow:auto;vertical-align:top} -table{border-collapse:collapse;border-spacing:0} -*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box} -html,body{font-size:100%} -body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto} -a:hover{cursor:pointer} -img,object,embed{max-width:100%;height:auto} -object,embed{height:100%} -img{-ms-interpolation-mode:bicubic} -#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none!important} -.left{float:left!important} -.right{float:right!important} -.text-left{text-align:left!important} -.text-right{text-align:right!important} -.text-center{text-align:center!important} -.text-justify{text-align:justify!important} -.hide{display:none} -.antialiased,body{-webkit-font-smoothing:antialiased} -img{display:inline-block;vertical-align:middle} -textarea{height:auto;min-height:50px} -select{width:100%} -p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6} -.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em} -div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr} -a{color:#2156a5;text-decoration:underline;line-height:inherit} -a:hover,a:focus{color:#1d4b8f} -a img{border:none} -p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} -p aside{font-size:.875em;line-height:1.35;font-style:italic} -h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} -h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0} -h1{font-size:2.125em} -h2{font-size:1.6875em} -h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} -h4,h5{font-size:1.125em} -h6{font-size:1em} -hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0} -em,i{font-style:italic;line-height:inherit} -strong,b{font-weight:bold;line-height:inherit} -small{font-size:60%;line-height:inherit} -code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} -ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} -ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em} -ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em} -ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit} -ul.square{list-style-type:square} -ul.circle{list-style-type:circle} -ul.disc{list-style-type:disc} -ul.no-bullet{list-style:none} -ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} -dl dt{margin-bottom:.3125em;font-weight:bold} -dl dd{margin-bottom:1.25em} -abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help} -abbr{text-transform:none} -blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} -blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)} -blockquote cite:before{content:"\2014 \0020"} -blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)} -blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} -@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} -h1{font-size:2.75em} -h2{font-size:2.3125em} -h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} -h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede} -table thead,table tfoot{background:#f7f8f7;font-weight:bold} -table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} -table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} -table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7} -table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6} -h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} -h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} -.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table} -.clearfix:after,.float-group:after{clear:both} -*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} -pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed} -.keyseq{color:rgba(51,51,51,.8)} -kbd{display:inline-block;color:rgba(0,0,0,.8);font-size:.75em;line-height:1.4;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:-.15em .15em 0 .15em;padding:.2em .6em .2em .5em;vertical-align:middle;white-space:nowrap} -.keyseq kbd:first-child{margin-left:0} -.keyseq kbd:last-child{margin-right:0} -.menuseq,.menu{color:rgba(0,0,0,.8)} -b.button:before,b.button:after{position:relative;top:-1px;font-weight:400} -b.button:before{content:"[";padding:0 3px 0 2px} -b.button:after{content:"]";padding:0 2px 0 3px} -p a>code:hover{color:rgba(0,0,0,.9)} -#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} -#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table} -#header:after,#content:after,#footnotes:after,#footer:after{clear:both} -#content{margin-top:1.25em} -#content:before{content:none} -#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} -#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8} -#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px} -#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap} -#header .details span:first-child{margin-left:-.125em} -#header .details span.email a{color:rgba(0,0,0,.85)} -#header .details br{display:none} -#header .details br+span:before{content:"\00a0\2013\00a0"} -#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} -#header .details br+span#revremark:before{content:"\00a0|\00a0"} -#header #revnumber{text-transform:capitalize} -#header #revnumber:after{content:"\00a0"} -#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} -#toc{border-bottom:1px solid #efefed;padding-bottom:.5em} -#toc>ul{margin-left:.125em} -#toc ul.sectlevel0>li>a{font-style:italic} -#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} -#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} -#toc a{text-decoration:none} -#toc a:active{text-decoration:underline} -#toctitle{color:#7a2518;font-size:1.2em} -@media only screen and (min-width:768px){#toctitle{font-size:1.375em} -body.toc2{padding-left:15em;padding-right:0} -#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} -#toc.toc2 #toctitle{margin-top:0;font-size:1.2em} -#toc.toc2>ul{font-size:.9em;margin-bottom:0} -#toc.toc2 ul ul{margin-left:0;padding-left:1em} -#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} -body.toc2.toc-right{padding-left:0;padding-right:15em} -body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} -#toc.toc2{width:20em} -#toc.toc2 #toctitle{font-size:1.375em} -#toc.toc2>ul{font-size:.95em} -#toc.toc2 ul ul{padding-left:1.25em} -body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} -#content #toc>:first-child{margin-top:0} -#content #toc>:last-child{margin-bottom:0} -#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em} -#footer-text{color:rgba(255,255,255,.8);line-height:1.44} -.sect1{padding-bottom:.625em} -@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed} -#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} -#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} -#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} -#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} -#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221} -.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} -.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic} -table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0} -.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)} -table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit} -.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} -.admonitionblock>table td.icon{text-align:center;width:80px} -.admonitionblock>table td.icon img{max-width:none} -.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} -.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)} -.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} -.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px} -.exampleblock>.content>:first-child{margin-top:0} -.exampleblock>.content>:last-child{margin-bottom:0} -.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} -.sidebarblock>:first-child{margin-top:0} -.sidebarblock>:last-child{margin-bottom:0} -.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} -.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} -.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8} -.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1} -.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em} -.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal} -@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)} -.listingblock pre.highlightjs{padding:0} -.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px} -.listingblock pre.prettyprint{border-width:0} -.listingblock>.content{position:relative} -.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999} -.listingblock:hover code[data-lang]:before{display:block} -.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999} -.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"} -table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none} -table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0} -table.pyhltable td.code{padding-left:.75em;padding-right:0} -pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8} -pre.pygments .lineno{display:inline-block;margin-right:.25em} -table.pyhltable .linenodiv{background:none!important;padding-right:0!important} -.quoteblock{margin:0 1em 1.25em 1.5em;display:table} -.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em} -.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} -.quoteblock blockquote{margin:0;padding:0;border:0} -.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)} -.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} -.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right} -.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)} -.quoteblock .quoteblock blockquote{padding:0 0 0 .75em} -.quoteblock .quoteblock blockquote:before{display:none} -.verseblock{margin:0 1em 1.25em 1em} -.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} -.verseblock pre strong{font-weight:400} -.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} -.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} -.quoteblock .attribution br,.verseblock .attribution br{display:none} -.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.05em;color:rgba(0,0,0,.6)} -.quoteblock.abstract{margin:0 0 1.25em 0;display:block} -.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0} -.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none} -table.tableblock{max-width:100%;border-collapse:separate} -table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0} -table.spread{width:100%} -table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} -table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0} -table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0} -table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0} -table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0} -table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0} -table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0} -table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0} -table.frame-all{border-width:1px} -table.frame-sides{border-width:0 1px} -table.frame-topbot{border-width:1px 0} -th.halign-left,td.halign-left{text-align:left} -th.halign-right,td.halign-right{text-align:right} -th.halign-center,td.halign-center{text-align:center} -th.valign-top,td.valign-top{vertical-align:top} -th.valign-bottom,td.valign-bottom{vertical-align:bottom} -th.valign-middle,td.valign-middle{vertical-align:middle} -table thead th,table tfoot th{font-weight:bold} -tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7} -tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} -p.tableblock>code:only-child{background:none;padding:0} -p.tableblock{font-size:1em} -td>div.verse{white-space:pre} -ol{margin-left:1.75em} -ul li ol{margin-left:1.5em} -dl dd{margin-left:1.125em} -dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} -ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} -ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none} -ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em} -ul.checklist li>p:first-child>.fa-check-square-o:first-child,ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em} -ul.checklist li>p:first-child>input[type="checkbox"]:first-child{position:relative;top:1px} -ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden} -ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block} -ul.inline>li>*{display:block} -.unstyled dl dt{font-weight:400;font-style:normal} -ol.arabic{list-style-type:decimal} -ol.decimal{list-style-type:decimal-leading-zero} -ol.loweralpha{list-style-type:lower-alpha} -ol.upperalpha{list-style-type:upper-alpha} -ol.lowerroman{list-style-type:lower-roman} -ol.upperroman{list-style-type:upper-roman} -ol.lowergreek{list-style-type:lower-greek} -.hdlist>table,.colist>table{border:0;background:none} -.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} -td.hdlist1{padding-right:.75em;font-weight:bold} -td.hdlist1,td.hdlist2{vertical-align:top} -.literalblock+.colist,.listingblock+.colist{margin-top:-.5em} -.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1} -.colist>table tr>td:last-of-type{padding:.25em 0} -.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd} -.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0} -.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em} -.imageblock>.title{margin-bottom:0} -.imageblock.thumb,.imageblock.th{border-width:6px} -.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} -.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} -.image.left{margin-right:.625em} -.image.right{margin-left:.625em} -a.image{text-decoration:none} -span.footnote,span.footnoteref{vertical-align:super;font-size:.875em} -span.footnote a,span.footnoteref a{text-decoration:none} -span.footnote a:active,span.footnoteref a:active{text-decoration:underline} -#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} -#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0} -#footnotes .footnote{padding:0 .375em;line-height:1.3;font-size:.875em;margin-left:1.2em;text-indent:-1.2em;margin-bottom:.2em} -#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none} -#footnotes .footnote:last-of-type{margin-bottom:0} -#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} -.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0} -.gist .file-data>table td.line-data{width:99%} -div.unbreakable{page-break-inside:avoid} -.big{font-size:larger} -.small{font-size:smaller} -.underline{text-decoration:underline} -.overline{text-decoration:overline} -.line-through{text-decoration:line-through} -.aqua{color:#00bfbf} -.aqua-background{background-color:#00fafa} -.black{color:#000} -.black-background{background-color:#000} -.blue{color:#0000bf} -.blue-background{background-color:#0000fa} -.fuchsia{color:#bf00bf} -.fuchsia-background{background-color:#fa00fa} -.gray{color:#606060} -.gray-background{background-color:#7d7d7d} -.green{color:#006000} -.green-background{background-color:#007d00} -.lime{color:#00bf00} -.lime-background{background-color:#00fa00} -.maroon{color:#600000} -.maroon-background{background-color:#7d0000} -.navy{color:#000060} -.navy-background{background-color:#00007d} -.olive{color:#606000} -.olive-background{background-color:#7d7d00} -.purple{color:#600060} -.purple-background{background-color:#7d007d} -.red{color:#bf0000} -.red-background{background-color:#fa0000} -.silver{color:#909090} -.silver-background{background-color:#bcbcbc} -.teal{color:#006060} -.teal-background{background-color:#007d7d} -.white{color:#bfbfbf} -.white-background{background-color:#fafafa} -.yellow{color:#bfbf00} -.yellow-background{background-color:#fafa00} -span.icon>.fa{cursor:default} -.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} -.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c} -.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} -.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900} -.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400} -.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000} -.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold} -.conum[data-value] *{color:#fff!important} -.conum[data-value]+b{display:none} -.conum[data-value]:after{content:attr(data-value)} -pre .conum[data-value]{position:relative;top:-.125em} -b.conum *{color:inherit!important} -.conum:not([data-value]):empty{display:none} -h1,h2{letter-spacing:-.01em} -dt,th.tableblock,td.content{text-rendering:optimizeLegibility} -p,td.content{letter-spacing:-.01em} -p strong,td.content strong{letter-spacing:-.005em} -p,blockquote,dt,td.content{font-size:1.0625rem} -p{margin-bottom:1.25rem} -.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} -.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc} -.print-only{display:none!important} -@media print{@page{margin:1.25cm .75cm} -*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important} -a{color:inherit!important;text-decoration:underline!important} -a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} -a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} -abbr[title]:after{content:" (" attr(title) ")"} -pre,blockquote,tr,img{page-break-inside:avoid} -thead{display:table-header-group} -img{max-width:100%!important} -p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} -h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} -#toc,.sidebarblock,.exampleblock>.content{background:none!important} -#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important} -.sect1{padding-bottom:0!important} -.sect1+.sect1{border:0!important} -#header>h1:first-child{margin-top:1.25rem} -body.book #header{text-align:center} -body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0} -body.book #header .details{border:0!important;display:block;padding:0!important} -body.book #header .details span:first-child{margin-left:0!important} -body.book #header .details br{display:block} -body.book #header .details br+span:before{content:none!important} -body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} -body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} -.listingblock code[data-lang]:before{display:block} -#footer{background:none!important;padding:0 .9375em} -#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em} -.hide-on-print{display:none!important} -.print-only{display:block!important} -.hide-for-print{display:none!important} -.show-for-print{display:inherit!important}} \ No newline at end of file +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { + display: block +} + +audio, canvas, video { + display: inline-block +} + +audio:not([controls]) { + display: none; + height: 0 +} + +[hidden], template { + display: none +} + +script { + display: none !important +} + +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100% +} + +body { + margin: 0 +} + +a { + background: transparent +} + +a:focus { + outline: thin dotted +} + +a:active, a:hover { + outline: 0 +} + +h1 { + font-size: 2em; + margin: .67em 0 +} + +abbr[title] { + border-bottom: 1px dotted +} + +b, strong { + font-weight: bold +} + +dfn { + font-style: italic +} + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0 +} + +mark { + background: #ff0; + color: #000 +} + +code, kbd, pre, samp { + font-family: monospace; + font-size: 1em +} + +pre { + white-space: pre-wrap +} + +q { + quotes: "\201C" "\201D" "\2018" "\2019" +} + +small { + font-size: 80% +} + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sup { + top: -.5em +} + +sub { + bottom: -.25em +} + +img { + border: 0 +} + +svg:not(:root) { + overflow: hidden +} + +figure { + margin: 0 +} + +fieldset { + border: 1px solid silver; + margin: 0 2px; + padding: .35em .625em .75em +} + +legend { + border: 0; + padding: 0 +} + +button, input, select, textarea { + font-family: inherit; + font-size: 100%; + margin: 0 +} + +button, input { + line-height: normal +} + +button, select { + text-transform: none +} + +button, html input[type="button"], input[type="reset"], input[type="submit"] { + -webkit-appearance: button; + cursor: pointer +} + +button[disabled], html input[disabled] { + cursor: default +} + +input[type="checkbox"], input[type="radio"] { + box-sizing: border-box; + padding: 0 +} + +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box +} + +input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none +} + +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0 +} + +textarea { + overflow: auto; + vertical-align: top +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +*, *:before, *:after { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box +} + +html, body { + font-size: 100% +} + +body { + background: #fff; + color: rgba(0, 0, 0, .8); + padding: 0; + margin: 0; + font-family: "Noto Serif", "DejaVu Serif", serif; + font-weight: 400; + font-style: normal; + line-height: 1; + position: relative; + cursor: auto +} + +a:hover { + cursor: pointer +} + +img, object, embed { + max-width: 100%; + height: auto +} + +object, embed { + height: 100% +} + +img { + -ms-interpolation-mode: bicubic +} + +#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { + max-width: none !important +} + +.left { + float: left !important +} + +.right { + float: right !important +} + +.text-left { + text-align: left !important +} + +.text-right { + text-align: right !important +} + +.text-center { + text-align: center !important +} + +.text-justify { + text-align: justify !important +} + +.hide { + display: none +} + +.antialiased, body { + -webkit-font-smoothing: antialiased +} + +img { + display: inline-block; + vertical-align: middle +} + +textarea { + height: auto; + min-height: 50px +} + +select { + width: 100% +} + +p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { + font-size: 1.21875em; + line-height: 1.6 +} + +.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { + line-height: 1.45; + color: #7a2518; + font-weight: 400; + margin-top: 0; + margin-bottom: .25em +} + +div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { + margin: 0; + padding: 0; + direction: ltr +} + +a { + color: #2156a5; + text-decoration: underline; + line-height: inherit +} + +a:hover, a:focus { + color: #1d4b8f +} + +a img { + border: none +} + +p { + font-family: inherit; + font-weight: 400; + font-size: 1em; + line-height: 1.6; + margin-bottom: 1.25em; + text-rendering: optimizeLegibility +} + +p aside { + font-size: .875em; + line-height: 1.35; + font-style: italic +} + +h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-weight: 300; + font-style: normal; + color: #ba3925; + text-rendering: optimizeLegibility; + margin-top: 1em; + margin-bottom: .5em; + line-height: 1.0125em +} + +h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { + font-size: 60%; + color: #e99b8f; + line-height: 0 +} + +h1 { + font-size: 2.125em +} + +h2 { + font-size: 1.6875em +} + +h3, #toctitle, .sidebarblock > .content > .title { + font-size: 1.375em +} + +h4, h5 { + font-size: 1.125em +} + +h6 { + font-size: 1em +} + +hr { + border: solid #ddddd8; + border-width: 1px 0 0; + clear: both; + margin: 1.25em 0 1.1875em; + height: 0 +} + +em, i { + font-style: italic; + line-height: inherit +} + +strong, b { + font-weight: bold; + line-height: inherit +} + +small { + font-size: 60%; + line-height: inherit +} + +code { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + font-weight: 400; + color: rgba(0, 0, 0, .9) +} + +ul, ol, dl { + font-size: 1em; + line-height: 1.6; + margin-bottom: 1.25em; + list-style-position: outside; + font-family: inherit +} + +ul, ol, ul.no-bullet, ol.no-bullet { + margin-left: 1.5em +} + +ul li ul, ul li ol { + margin-left: 1.25em; + margin-bottom: 0; + font-size: 1em +} + +ul.square li ul, ul.circle li ul, ul.disc li ul { + list-style: inherit +} + +ul.square { + list-style-type: square +} + +ul.circle { + list-style-type: circle +} + +ul.disc { + list-style-type: disc +} + +ul.no-bullet { + list-style: none +} + +ol li ul, ol li ol { + margin-left: 1.25em; + margin-bottom: 0 +} + +dl dt { + margin-bottom: .3125em; + font-weight: bold +} + +dl dd { + margin-bottom: 1.25em +} + +abbr, acronym { + text-transform: uppercase; + font-size: 90%; + color: rgba(0, 0, 0, .8); + border-bottom: 1px dotted #ddd; + cursor: help +} + +abbr { + text-transform: none +} + +blockquote { + margin: 0 0 1.25em; + padding: .5625em 1.25em 0 1.1875em; + border-left: 1px solid #ddd +} + +blockquote cite { + display: block; + font-size: .9375em; + color: rgba(0, 0, 0, .6) +} + +blockquote cite:before { + content: "\2014 \0020" +} + +blockquote cite a, blockquote cite a:visited { + color: rgba(0, 0, 0, .6) +} + +blockquote, blockquote p { + line-height: 1.6; + color: rgba(0, 0, 0, .85) +} + +@media only screen and (min-width: 768px) { + h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + line-height: 1.2 + } + + h1 { + font-size: 2.75em + } + + h2 { + font-size: 2.3125em + } + + h3, #toctitle, .sidebarblock > .content > .title { + font-size: 1.6875em + } + + h4 { + font-size: 1.4375em + } +} + +table { + background: #fff; + margin-bottom: 1.25em; + border: solid 1px #dedede +} + +table thead, table tfoot { + background: #f7f8f7; + font-weight: bold +} + +table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { + padding: .5em .625em .625em; + font-size: inherit; + color: rgba(0, 0, 0, .8); + text-align: left +} + +table tr th, table tr td { + padding: .5625em .625em; + font-size: inherit; + color: rgba(0, 0, 0, .8) +} + +table tr.even, table tr.alt, table tr:nth-of-type(even) { + background: #f8f8f7 +} + +table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { + display: table-cell; + line-height: 1.6 +} + +h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + line-height: 1.2; + word-spacing: -.05em +} + +h1 strong, h2 strong, h3 strong, #toctitle strong, .sidebarblock > .content > .title strong, h4 strong, h5 strong, h6 strong { + font-weight: 400 +} + +.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { + content: " "; + display: table +} + +.clearfix:after, .float-group:after { + clear: both +} + +*:not(pre) > code { + font-size: .9375em; + font-style: normal !important; + letter-spacing: 0; + padding: .1em .5ex; + word-spacing: -.15em; + background-color: #f7f7f8; + -webkit-border-radius: 4px; + border-radius: 4px; + line-height: 1.45; + text-rendering: optimizeSpeed +} + +pre, pre > code { + line-height: 1.45; + color: rgba(0, 0, 0, .9); + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + font-weight: 400; + text-rendering: optimizeSpeed +} + +.keyseq { + color: rgba(51, 51, 51, .8) +} + +kbd { + display: inline-block; + color: rgba(0, 0, 0, .8); + font-size: .75em; + line-height: 1.4; + background-color: #f7f7f7; + border: 1px solid #ccc; + -webkit-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .2), 0 0 0 .1em white inset; + box-shadow: 0 1px 0 rgba(0, 0, 0, .2), 0 0 0 .1em #fff inset; + margin: -.15em .15em 0 .15em; + padding: .2em .6em .2em .5em; + vertical-align: middle; + white-space: nowrap +} + +.keyseq kbd:first-child { + margin-left: 0 +} + +.keyseq kbd:last-child { + margin-right: 0 +} + +.menuseq, .menu { + color: rgba(0, 0, 0, .8) +} + +b.button:before, b.button:after { + position: relative; + top: -1px; + font-weight: 400 +} + +b.button:before { + content: "["; + padding: 0 3px 0 2px +} + +b.button:after { + content: "]"; + padding: 0 2px 0 3px +} + +p a > code:hover { + color: rgba(0, 0, 0, .9) +} + +#header, #content, #footnotes, #footer { + width: 100%; + margin-left: auto; + margin-right: auto; + margin-top: 0; + margin-bottom: 0; + max-width: 62.5em; + *zoom: 1; + position: relative; + padding-left: .9375em; + padding-right: .9375em +} + +#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { + content: " "; + display: table +} + +#header:after, #content:after, #footnotes:after, #footer:after { + clear: both +} + +#content { + margin-top: 1.25em +} + +#content:before { + content: none +} + +#header > h1:first-child { + color: rgba(0, 0, 0, .85); + margin-top: 2.25rem; + margin-bottom: 0 +} + +#header > h1:first-child + #toc { + margin-top: 8px; + border-top: 1px solid #ddddd8 +} + +#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { + border-bottom: 1px solid #ddddd8; + padding-bottom: 8px +} + +#header .details { + border-bottom: 1px solid #ddddd8; + line-height: 1.45; + padding-top: .25em; + padding-bottom: .25em; + padding-left: .25em; + color: rgba(0, 0, 0, .6); + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-flow: row wrap; + -webkit-flex-flow: row wrap; + flex-flow: row wrap +} + +#header .details span:first-child { + margin-left: -.125em +} + +#header .details span.email a { + color: rgba(0, 0, 0, .85) +} + +#header .details br { + display: none +} + +#header .details br + span:before { + content: "\00a0\2013\00a0" +} + +#header .details br + span.author:before { + content: "\00a0\22c5\00a0"; + color: rgba(0, 0, 0, .85) +} + +#header .details br + span#revremark:before { + content: "\00a0|\00a0" +} + +#header #revnumber { + text-transform: capitalize +} + +#header #revnumber:after { + content: "\00a0" +} + +#content > h1:first-child:not([class]) { + color: rgba(0, 0, 0, .85); + border-bottom: 1px solid #ddddd8; + padding-bottom: 8px; + margin-top: 0; + padding-top: 1rem; + margin-bottom: 1.25rem +} + +#toc { + border-bottom: 1px solid #efefed; + padding-bottom: .5em +} + +#toc > ul { + margin-left: .125em +} + +#toc ul.sectlevel0 > li > a { + font-style: italic +} + +#toc ul.sectlevel0 ul.sectlevel1 { + margin: .5em 0 +} + +#toc ul { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + list-style-type: none +} + +#toc a { + text-decoration: none +} + +#toc a:active { + text-decoration: underline +} + +#toctitle { + color: #7a2518; + font-size: 1.2em +} + +@media only screen and (min-width: 768px) { + #toctitle { + font-size: 1.375em + } + + body.toc2 { + padding-left: 15em; + padding-right: 0 + } + + #toc.toc2 { + margin-top: 0 !important; + background-color: #f8f8f7; + position: fixed; + width: 15em; + left: 0; + top: 0; + border-right: 1px solid #efefed; + border-top-width: 0 !important; + border-bottom-width: 0 !important; + z-index: 1000; + padding: 1.25em 1em; + height: 100%; + overflow: auto + } + + #toc.toc2 #toctitle { + margin-top: 0; + font-size: 1.2em + } + + #toc.toc2 > ul { + font-size: .9em; + margin-bottom: 0 + } + + #toc.toc2 ul ul { + margin-left: 0; + padding-left: 1em + } + + #toc.toc2 ul.sectlevel0 ul.sectlevel1 { + padding-left: 0; + margin-top: .5em; + margin-bottom: .5em + } + + body.toc2.toc-right { + padding-left: 0; + padding-right: 15em + } + + body.toc2.toc-right #toc.toc2 { + border-right-width: 0; + border-left: 1px solid #efefed; + left: auto; + right: 0 + } +} + +@media only screen and (min-width: 1280px) { + body.toc2 { + padding-left: 20em; + padding-right: 0 + } + + #toc.toc2 { + width: 20em + } + + #toc.toc2 #toctitle { + font-size: 1.375em + } + + #toc.toc2 > ul { + font-size: .95em + } + + #toc.toc2 ul ul { + padding-left: 1.25em + } + + body.toc2.toc-right { + padding-left: 0; + padding-right: 20em + } +} + +#content #toc { + border-style: solid; + border-width: 1px; + border-color: #e0e0dc; + margin-bottom: 1.25em; + padding: 1.25em; + background: #f8f8f7; + -webkit-border-radius: 4px; + border-radius: 4px +} + +#content #toc > :first-child { + margin-top: 0 +} + +#content #toc > :last-child { + margin-bottom: 0 +} + +#footer { + max-width: 100%; + background-color: rgba(0, 0, 0, .8); + padding: 1.25em +} + +#footer-text { + color: rgba(255, 255, 255, .8); + line-height: 1.44 +} + +.sect1 { + padding-bottom: .625em +} + +@media only screen and (min-width: 768px) { + .sect1 { + padding-bottom: 1.25em + } +} + +.sect1 + .sect1 { + border-top: 1px solid #efefed +} + +#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { + position: absolute; + z-index: 1001; + width: 1.5ex; + margin-left: -1.5ex; + display: block; + text-decoration: none !important; + visibility: hidden; + text-align: center; + font-weight: 400 +} + +#content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { + content: "\00A7"; + font-size: .85em; + display: block; + padding-top: .1em +} + +#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { + visibility: visible +} + +#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { + color: #ba3925; + text-decoration: none +} + +#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { + color: #a53221 +} + +.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { + margin-bottom: 1.25em +} + +.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { + text-rendering: optimizeLegibility; + text-align: left; + font-family: "Noto Serif", "DejaVu Serif", serif; + font-size: 1rem; + font-style: italic +} + +table.tableblock > caption.title { + white-space: nowrap; + overflow: visible; + max-width: 0 +} + +.paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { + color: rgba(0, 0, 0, .85) +} + +table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { + font-size: inherit +} + +.admonitionblock > table { + border-collapse: separate; + border: 0; + background: none; + width: 100% +} + +.admonitionblock > table td.icon { + text-align: center; + width: 80px +} + +.admonitionblock > table td.icon img { + max-width: none +} + +.admonitionblock > table td.icon .title { + font-weight: bold; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + text-transform: uppercase +} + +.admonitionblock > table td.content { + padding-left: 1.125em; + padding-right: 1.25em; + border-left: 1px solid #ddddd8; + color: rgba(0, 0, 0, .6) +} + +.admonitionblock > table td.content > :last-child > :last-child { + margin-bottom: 0 +} + +.exampleblock > .content { + border-style: solid; + border-width: 1px; + border-color: #e6e6e6; + margin-bottom: 1.25em; + padding: 1.25em; + background: #fff; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.exampleblock > .content > :first-child { + margin-top: 0 +} + +.exampleblock > .content > :last-child { + margin-bottom: 0 +} + +.sidebarblock { + border-style: solid; + border-width: 1px; + border-color: #e0e0dc; + margin-bottom: 1.25em; + padding: 1.25em; + background: #f8f8f7; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.sidebarblock > :first-child { + margin-top: 0 +} + +.sidebarblock > :last-child { + margin-bottom: 0 +} + +.sidebarblock > .content > .title { + color: #7a2518; + margin-top: 0; + text-align: center +} + +.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { + margin-bottom: 0 +} + +.literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { + background: #f7f7f8 +} + +.sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { + background: #f2f1f1 +} + +.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { + -webkit-border-radius: 4px; + border-radius: 4px; + word-wrap: break-word; + padding: 1em; + font-size: .8125em +} + +.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { + overflow-x: auto; + white-space: pre; + word-wrap: normal +} + +@media only screen and (min-width: 768px) { + .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { + font-size: .90625em + } +} + +@media only screen and (min-width: 1280px) { + .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { + font-size: 1em + } +} + +.literalblock.output pre { + color: #f7f7f8; + background-color: rgba(0, 0, 0, .9) +} + +.listingblock pre.highlightjs { + padding: 0 +} + +.listingblock pre.highlightjs > code { + padding: 1em; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.listingblock pre.prettyprint { + border-width: 0 +} + +.listingblock > .content { + position: relative +} + +.listingblock code[data-lang]:before { + display: none; + content: attr(data-lang); + position: absolute; + font-size: .75em; + top: .425rem; + right: .5rem; + line-height: 1; + text-transform: uppercase; + color: #999 +} + +.listingblock:hover code[data-lang]:before { + display: block +} + +.listingblock.terminal pre .command:before { + content: attr(data-prompt); + padding-right: .5em; + color: #999 +} + +.listingblock.terminal pre .command:not([data-prompt]):before { + content: "$" +} + +table.pyhltable { + border-collapse: separate; + border: 0; + margin-bottom: 0; + background: none +} + +table.pyhltable td { + vertical-align: top; + padding-top: 0; + padding-bottom: 0 +} + +table.pyhltable td.code { + padding-left: .75em; + padding-right: 0 +} + +pre.pygments .lineno, table.pyhltable td:not(.code) { + color: #999; + padding-left: 0; + padding-right: .5em; + border-right: 1px solid #ddddd8 +} + +pre.pygments .lineno { + display: inline-block; + margin-right: .25em +} + +table.pyhltable .linenodiv { + background: none !important; + padding-right: 0 !important +} + +.quoteblock { + margin: 0 1em 1.25em 1.5em; + display: table +} + +.quoteblock > .title { + margin-left: -1.5em; + margin-bottom: .75em +} + +.quoteblock blockquote, .quoteblock blockquote p { + color: rgba(0, 0, 0, .85); + font-size: 1.15rem; + line-height: 1.75; + word-spacing: .1em; + letter-spacing: 0; + font-style: italic; + text-align: justify +} + +.quoteblock blockquote { + margin: 0; + padding: 0; + border: 0 +} + +.quoteblock blockquote:before { + content: "\201c"; + float: left; + font-size: 2.75em; + font-weight: bold; + line-height: .6em; + margin-left: -.6em; + color: #7a2518; + text-shadow: 0 1px 2px rgba(0, 0, 0, .1) +} + +.quoteblock blockquote > .paragraph:last-child p { + margin-bottom: 0 +} + +.quoteblock .attribution { + margin-top: .5em; + margin-right: .5ex; + text-align: right +} + +.quoteblock .quoteblock { + margin-left: 0; + margin-right: 0; + padding: .5em 0; + border-left: 3px solid rgba(0, 0, 0, .6) +} + +.quoteblock .quoteblock blockquote { + padding: 0 0 0 .75em +} + +.quoteblock .quoteblock blockquote:before { + display: none +} + +.verseblock { + margin: 0 1em 1.25em 1em +} + +.verseblock pre { + font-family: "Open Sans", "DejaVu Sans", sans; + font-size: 1.15rem; + color: rgba(0, 0, 0, .85); + font-weight: 300; + text-rendering: optimizeLegibility +} + +.verseblock pre strong { + font-weight: 400 +} + +.verseblock .attribution { + margin-top: 1.25rem; + margin-left: .5ex +} + +.quoteblock .attribution, .verseblock .attribution { + font-size: .9375em; + line-height: 1.45; + font-style: italic +} + +.quoteblock .attribution br, .verseblock .attribution br { + display: none +} + +.quoteblock .attribution cite, .verseblock .attribution cite { + display: block; + letter-spacing: -.05em; + color: rgba(0, 0, 0, .6) +} + +.quoteblock.abstract { + margin: 0 0 1.25em 0; + display: block +} + +.quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { + text-align: left; + word-spacing: 0 +} + +.quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { + display: none +} + +table.tableblock { + max-width: 100%; + border-collapse: separate +} + +table.tableblock td > .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { + margin-bottom: 0 +} + +table.spread { + width: 100% +} + +table.tableblock, th.tableblock, td.tableblock { + border: 0 solid #dedede +} + +table.grid-all th.tableblock, table.grid-all td.tableblock { + border-width: 0 1px 1px 0 +} + +table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { + border-width: 1px 1px 0 0 +} + +table.grid-cols th.tableblock, table.grid-cols td.tableblock { + border-width: 0 1px 0 0 +} + +table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { + border-right-width: 0 +} + +table.grid-rows th.tableblock, table.grid-rows td.tableblock { + border-width: 0 0 1px 0 +} + +table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { + border-bottom-width: 0 +} + +table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { + border-width: 1px 0 0 0 +} + +table.frame-all { + border-width: 1px +} + +table.frame-sides { + border-width: 0 1px +} + +table.frame-topbot { + border-width: 1px 0 +} + +th.halign-left, td.halign-left { + text-align: left +} + +th.halign-right, td.halign-right { + text-align: right +} + +th.halign-center, td.halign-center { + text-align: center +} + +th.valign-top, td.valign-top { + vertical-align: top +} + +th.valign-bottom, td.valign-bottom { + vertical-align: bottom +} + +th.valign-middle, td.valign-middle { + vertical-align: middle +} + +table thead th, table tfoot th { + font-weight: bold +} + +tbody tr th { + display: table-cell; + line-height: 1.6; + background: #f7f8f7 +} + +tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { + color: rgba(0, 0, 0, .8); + font-weight: bold +} + +p.tableblock > code:only-child { + background: none; + padding: 0 +} + +p.tableblock { + font-size: 1em +} + +td > div.verse { + white-space: pre +} + +ol { + margin-left: 1.75em +} + +ul li ol { + margin-left: 1.5em +} + +dl dd { + margin-left: 1.125em +} + +dl dd:last-child, dl dd:last-child > :last-child { + margin-bottom: 0 +} + +ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { + margin-bottom: .625em +} + +ul.unstyled, ol.unnumbered, ul.checklist, ul.none { + list-style-type: none +} + +ul.unstyled, ol.unnumbered, ul.checklist { + margin-left: .625em +} + +ul.checklist li > p:first-child > .fa-check-square-o:first-child, ul.checklist li > p:first-child > input[type="checkbox"]:first-child { + margin-right: .25em +} + +ul.checklist li > p:first-child > input[type="checkbox"]:first-child { + position: relative; + top: 1px +} + +ul.inline { + margin: 0 auto .625em auto; + margin-left: -1.375em; + margin-right: 0; + padding: 0; + list-style: none; + overflow: hidden +} + +ul.inline > li { + list-style: none; + float: left; + margin-left: 1.375em; + display: block +} + +ul.inline > li > * { + display: block +} + +.unstyled dl dt { + font-weight: 400; + font-style: normal +} + +ol.arabic { + list-style-type: decimal +} + +ol.decimal { + list-style-type: decimal-leading-zero +} + +ol.loweralpha { + list-style-type: lower-alpha +} + +ol.upperalpha { + list-style-type: upper-alpha +} + +ol.lowerroman { + list-style-type: lower-roman +} + +ol.upperroman { + list-style-type: upper-roman +} + +ol.lowergreek { + list-style-type: lower-greek +} + +.hdlist > table, .colist > table { + border: 0; + background: none +} + +.hdlist > table > tbody > tr, .colist > table > tbody > tr { + background: none +} + +td.hdlist1 { + padding-right: .75em; + font-weight: bold +} + +td.hdlist1, td.hdlist2 { + vertical-align: top +} + +.literalblock + .colist, .listingblock + .colist { + margin-top: -.5em +} + +.colist > table tr > td:first-of-type { + padding: 0 .75em; + line-height: 1 +} + +.colist > table tr > td:last-of-type { + padding: .25em 0 +} + +.thumb, .th { + line-height: 0; + display: inline-block; + border: solid 4px #fff; + -webkit-box-shadow: 0 0 0 1px #ddd; + box-shadow: 0 0 0 1px #ddd +} + +.imageblock.left, .imageblock[style*="float: left"] { + margin: .25em .625em 1.25em 0 +} + +.imageblock.right, .imageblock[style*="float: right"] { + margin: .25em 0 1.25em .625em +} + +.imageblock > .title { + margin-bottom: 0 +} + +.imageblock.thumb, .imageblock.th { + border-width: 6px +} + +.imageblock.thumb > .title, .imageblock.th > .title { + padding: 0 .125em +} + +.image.left, .image.right { + margin-top: .25em; + margin-bottom: .25em; + display: inline-block; + line-height: 0 +} + +.image.left { + margin-right: .625em +} + +.image.right { + margin-left: .625em +} + +a.image { + text-decoration: none +} + +span.footnote, span.footnoteref { + vertical-align: super; + font-size: .875em +} + +span.footnote a, span.footnoteref a { + text-decoration: none +} + +span.footnote a:active, span.footnoteref a:active { + text-decoration: underline +} + +#footnotes { + padding-top: .75em; + padding-bottom: .75em; + margin-bottom: .625em +} + +#footnotes hr { + width: 20%; + min-width: 6.25em; + margin: -.25em 0 .75em 0; + border-width: 1px 0 0 0 +} + +#footnotes .footnote { + padding: 0 .375em; + line-height: 1.3; + font-size: .875em; + margin-left: 1.2em; + text-indent: -1.2em; + margin-bottom: .2em +} + +#footnotes .footnote a:first-of-type { + font-weight: bold; + text-decoration: none +} + +#footnotes .footnote:last-of-type { + margin-bottom: 0 +} + +#content #footnotes { + margin-top: -.625em; + margin-bottom: 0; + padding: .75em 0 +} + +.gist .file-data > table { + border: 0; + background: #fff; + width: 100%; + margin-bottom: 0 +} + +.gist .file-data > table td.line-data { + width: 99% +} + +div.unbreakable { + page-break-inside: avoid +} + +.big { + font-size: larger +} + +.small { + font-size: smaller +} + +.underline { + text-decoration: underline +} + +.overline { + text-decoration: overline +} + +.line-through { + text-decoration: line-through +} + +.aqua { + color: #00bfbf +} + +.aqua-background { + background-color: #00fafa +} + +.black { + color: #000 +} + +.black-background { + background-color: #000 +} + +.blue { + color: #0000bf +} + +.blue-background { + background-color: #0000fa +} + +.fuchsia { + color: #bf00bf +} + +.fuchsia-background { + background-color: #fa00fa +} + +.gray { + color: #606060 +} + +.gray-background { + background-color: #7d7d7d +} + +.green { + color: #006000 +} + +.green-background { + background-color: #007d00 +} + +.lime { + color: #00bf00 +} + +.lime-background { + background-color: #00fa00 +} + +.maroon { + color: #600000 +} + +.maroon-background { + background-color: #7d0000 +} + +.navy { + color: #000060 +} + +.navy-background { + background-color: #00007d +} + +.olive { + color: #606000 +} + +.olive-background { + background-color: #7d7d00 +} + +.purple { + color: #600060 +} + +.purple-background { + background-color: #7d007d +} + +.red { + color: #bf0000 +} + +.red-background { + background-color: #fa0000 +} + +.silver { + color: #909090 +} + +.silver-background { + background-color: #bcbcbc +} + +.teal { + color: #006060 +} + +.teal-background { + background-color: #007d7d +} + +.white { + color: #bfbfbf +} + +.white-background { + background-color: #fafafa +} + +.yellow { + color: #bfbf00 +} + +.yellow-background { + background-color: #fafa00 +} + +span.icon > .fa { + cursor: default +} + +.admonitionblock td.icon [class^="fa icon-"] { + font-size: 2.5em; + text-shadow: 1px 1px 2px rgba(0, 0, 0, .5); + cursor: default +} + +.admonitionblock td.icon .icon-note:before { + content: "\f05a"; + color: #19407c +} + +.admonitionblock td.icon .icon-tip:before { + content: "\f0eb"; + text-shadow: 1px 1px 2px rgba(155, 155, 0, .8); + color: #111 +} + +.admonitionblock td.icon .icon-warning:before { + content: "\f071"; + color: #bf6900 +} + +.admonitionblock td.icon .icon-caution:before { + content: "\f06d"; + color: #bf3400 +} + +.admonitionblock td.icon .icon-important:before { + content: "\f06a"; + color: #bf0000 +} + +.conum[data-value] { + display: inline-block; + color: #fff !important; + background-color: rgba(0, 0, 0, .8); + -webkit-border-radius: 100px; + border-radius: 100px; + text-align: center; + font-size: .75em; + width: 1.67em; + height: 1.67em; + line-height: 1.67em; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-style: normal; + font-weight: bold +} + +.conum[data-value] * { + color: #fff !important +} + +.conum[data-value] + b { + display: none +} + +.conum[data-value]:after { + content: attr(data-value) +} + +pre .conum[data-value] { + position: relative; + top: -.125em +} + +b.conum * { + color: inherit !important +} + +.conum:not([data-value]):empty { + display: none +} + +h1, h2 { + letter-spacing: -.01em +} + +dt, th.tableblock, td.content { + text-rendering: optimizeLegibility +} + +p, td.content { + letter-spacing: -.01em +} + +p strong, td.content strong { + letter-spacing: -.005em +} + +p, blockquote, dt, td.content { + font-size: 1.0625rem +} + +p { + margin-bottom: 1.25rem +} + +.sidebarblock p, .sidebarblock dt, .sidebarblock td.content, p.tableblock { + font-size: 1em +} + +.exampleblock > .content { + background-color: #fffef7; + border-color: #e0e0dc; + -webkit-box-shadow: 0 1px 4px #e0e0dc; + box-shadow: 0 1px 4px #e0e0dc +} + +.print-only { + display: none !important +} + +@media print { + @page { + margin: 1.25cm .75cm + } + + * { + -webkit-box-shadow: none !important; + box-shadow: none !important; + text-shadow: none !important + } + + a { + color: inherit !important; + text-decoration: underline !important + } + + a.bare, a[href^="#"], a[href^="mailto:"] { + text-decoration: none !important + } + + a[href^="http:"]:not(.bare):after, a[href^="https:"]:not(.bare):after { + content: "(" attr(href) ")"; + display: inline-block; + font-size: .875em; + padding-left: .25em + } + + abbr[title]:after { + content: " (" attr(title) ")" + } + + pre, blockquote, tr, img { + page-break-inside: avoid + } + + thead { + display: table-header-group + } + + img { + max-width: 100% !important + } + + p, blockquote, dt, td.content { + font-size: 1em; + orphans: 3; + widows: 3 + } + + h2, h3, #toctitle, .sidebarblock > .content > .title { + page-break-after: avoid + } + + #toc, .sidebarblock, .exampleblock > .content { + background: none !important + } + + #toc { + border-bottom: 1px solid #ddddd8 !important; + padding-bottom: 0 !important + } + + .sect1 { + padding-bottom: 0 !important + } + + .sect1 + .sect1 { + border: 0 !important + } + + #header > h1:first-child { + margin-top: 1.25rem + } + + body.book #header { + text-align: center + } + + body.book #header > h1:first-child { + border: 0 !important; + margin: 2.5em 0 1em 0 + } + + body.book #header .details { + border: 0 !important; + display: block; + padding: 0 !important + } + + body.book #header .details span:first-child { + margin-left: 0 !important + } + + body.book #header .details br { + display: block + } + + body.book #header .details br + span:before { + content: none !important + } + + body.book #toc { + border: 0 !important; + text-align: left !important; + padding: 0 !important; + margin: 0 !important + } + + body.book #toc, body.book #preamble, body.book h1.sect0, body.book .sect1 > h2 { + page-break-before: always + } + + .listingblock code[data-lang]:before { + display: block + } + + #footer { + background: none !important; + padding: 0 .9375em + } + + #footer-text { + color: rgba(0, 0, 0, .6) !important; + font-size: .9em + } + + .hide-on-print { + display: none !important + } + + .print-only { + display: block !important + } + + .hide-for-print { + display: none !important + } + + .show-for-print { + display: inherit !important + } +} diff --git a/docs/pom.xml b/docs/pom.xml index 3896e177..3f15becc 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/mvnw b/mvnw index 25f750cb..5551fde8 100755 --- a/mvnw +++ b/mvnw @@ -54,38 +54,16 @@ case "`uname`" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; esac if [ -z "$JAVA_HOME" ] ; then @@ -130,7 +108,7 @@ if $cygwin ; then CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi -# For Migwn, ensure paths are in UNIX format before anything is touched +# For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then [ -n "$M2_HOME" ] && M2_HOME="`(cd "$M2_HOME"; pwd)`" @@ -184,27 +162,28 @@ fi CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` -fi - # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { - local basedir=$(pwd) - local wdir=$(pwd) + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir=$wdir break fi - wdir=$(cd "$wdir/.."; pwd) + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround done echo "${basedir}" } @@ -216,38 +195,92 @@ concat_lines() { fi } -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -echo "Running version check" -VERSION=$( sed '\!//' -e 's!.*$!!' ) -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} ${MAVEN_ARGS} "$@" + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100755 index 00000000..48363fa6 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM 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 set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index 151e33d6..88334b85 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 @@ -25,14 +25,24 @@ 2.1.1.BUILD-SNAPSHOT 2.1.1.BUILD-SNAPSHOT 1.0.3.RELEASE - 2.1.1.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT + Fishtown.BUILD-SNAPSHOT + + true + true + + true + https://github.com/spring-cloud/spring-cloud-consul - scm:git:git://github.com/spring-cloud/spring-cloud-consul.git - scm:git:ssh://git@github.com/spring-cloud/spring-cloud-consul.git + scm:git:git://github.com/spring-cloud/spring-cloud-consul.git + + + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-consul.git + HEAD @@ -62,9 +72,26 @@ 1.8 + + io.spring.javaformat + spring-javaformat-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + diff --git a/scripts/build.sh b/scripts/build.sh index 47399467..9da481d1 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,5 +1,6 @@ #!/bin/bash +trap 'pkill -9 consul; EXIT' 0 ./src/main/bash/travis_install_consul.sh ./src/test/bash/travis_run_consul.sh ./mvnw clean install -B -Pdocs ${@} diff --git a/spring-cloud-consul-binder/pom.xml b/spring-cloud-consul-binder/pom.xml index 5d0b7250..5b18eb3e 100644 --- a/spring-cloud-consul-binder/pom.xml +++ b/spring-cloud-consul-binder/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulBinder.java b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulBinder.java index b18321b4..341fb30f 100644 --- a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulBinder.java +++ b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -29,7 +29,8 @@ import org.springframework.util.Assert; /** * @author Spencer Gibb */ -public class ConsulBinder extends AbstractBinder { +public class ConsulBinder + extends AbstractBinder { private static final String BEAN_NAME_TEMPLATE = "outbound.%s"; @@ -40,8 +41,10 @@ public class ConsulBinder extends AbstractBinder doBindConsumer(String name, String group, MessageChannel inputChannel, ConsumerProperties properties) { - ConsulInboundMessageProducer messageProducer = new ConsulInboundMessageProducer(this.eventService); + protected Binding doBindConsumer(String name, String group, + MessageChannel inputChannel, ConsumerProperties properties) { + ConsulInboundMessageProducer messageProducer = new ConsulInboundMessageProducer( + this.eventService); messageProducer.setOutputChannel(inputChannel); messageProducer.setBeanFactory(this.getBeanFactory()); messageProducer.afterPropertiesSet(); @@ -51,13 +54,16 @@ public class ConsulBinder extends AbstractBinder doBindProducer(String name, MessageChannel channel, ProducerProperties properties) { + protected Binding doBindProducer(String name, MessageChannel channel, + ProducerProperties properties) { Assert.isInstanceOf(SubscribableChannel.class, channel); - logger.debug("Binding Consul client to eventName " + name); - ConsulSendingHandler sendingHandler = new ConsulSendingHandler(this.eventService.getConsulClient(), name); + this.logger.debug("Binding Consul client to eventName " + name); + ConsulSendingHandler sendingHandler = new ConsulSendingHandler( + this.eventService.getConsulClient(), name); - EventDrivenConsumer consumer = new EventDrivenConsumer((SubscribableChannel) channel, sendingHandler); + EventDrivenConsumer consumer = new EventDrivenConsumer( + (SubscribableChannel) channel, sendingHandler); consumer.setBeanFactory(getBeanFactory()); consumer.setBeanName(String.format(BEAN_NAME_TEMPLATE, name)); consumer.afterPropertiesSet(); @@ -65,4 +71,5 @@ public class ConsulBinder extends AbstractBinder(name, null, channel, consumer); } + } diff --git a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducer.java b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducer.java index 80050f33..ba70a30b 100644 --- a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducer.java +++ b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ package org.springframework.cloud.consul.binder; -import static org.springframework.util.Base64Utils.decodeFromString; - import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -25,24 +23,31 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import com.ecwid.consul.v1.OperationException; +import com.ecwid.consul.v1.event.model.Event; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.integration.endpoint.MessageProducerSupport; -import com.ecwid.consul.v1.event.model.Event; +import static org.springframework.util.Base64Utils.decodeFromString; /** * Adapter that receives Messages from Consul Events, converts them into Spring * Integration Messages, and sends the results to a Message Channel. + * * @author Spencer Gibb */ public class ConsulInboundMessageProducer extends MessageProducerSupport { - protected static final Log logger = LogFactory.getLog(ConsulInboundMessageProducer.class); + protected static final Log logger = LogFactory + .getLog(ConsulInboundMessageProducer.class); + + private final ScheduledExecutorService scheduler; + + private final Runnable eventsRunnable; private EventService eventService; - private final ScheduledExecutorService scheduler; - private final Runnable eventsRunnable; + private ScheduledFuture eventsHandle; public ConsulInboundMessageProducer(EventService eventService) { @@ -75,8 +80,9 @@ public class ConsulInboundMessageProducer extends MessageProducerSupport { @Override protected void doStart() { - //TODO: make configurable - eventsHandle = this.scheduler.scheduleWithFixedDelay(eventsRunnable, 500, 500, TimeUnit.MILLISECONDS); + // TODO: make configurable + this.eventsHandle = this.scheduler.scheduleWithFixedDelay(this.eventsRunnable, + 500, 500, TimeUnit.MILLISECONDS); } @Override @@ -90,20 +96,22 @@ public class ConsulInboundMessageProducer extends MessageProducerSupport { // @Scheduled(fixedDelayString = "${spring.cloud.consul.binder.eventDelay:30000}") public void getEvents() { try { - List events = eventService.watch(); + List events = this.eventService.watch(); for (Event event : events) { // Map headers = new HashMap<>(); // headers.put(MessageHeaders.REPLY_CHANNEL, outputChannel.) String decoded = new String(decodeFromString(event.getPayload())); sendMessage(getMessageBuilderFactory().withPayload(decoded) - // TODO: support headers + // TODO: support headers .build()); } - } catch (OperationException e) { + } + catch (OperationException e) { if (logger.isErrorEnabled()) { logger.error("Error getting consul events: " + e); } - } catch (Exception e) { + } + catch (Exception e) { if (logger.isErrorEnabled()) { logger.error("Error getting consul events: " + e.getMessage()); } @@ -112,4 +120,5 @@ public class ConsulInboundMessageProducer extends MessageProducerSupport { } } } + } diff --git a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulSendingHandler.java b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulSendingHandler.java index f18fe60c..fd51dc3a 100644 --- a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulSendingHandler.java +++ b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulSendingHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,23 +16,24 @@ package org.springframework.cloud.consul.binder; -import org.springframework.integration.handler.AbstractMessageHandler; -import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; -import org.springframework.messaging.Message; - import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.QueryParams; import com.ecwid.consul.v1.Response; import com.ecwid.consul.v1.event.model.Event; import com.ecwid.consul.v1.event.model.EventParams; +import org.springframework.integration.handler.AbstractMessageHandler; +import org.springframework.messaging.Message; + /** - * Adapter that converts and sends Messages as Consul events + * Adapter that converts and sends Messages as Consul events. + * * @author Spencer Gibb */ public class ConsulSendingHandler extends AbstractMessageHandler { private final ConsulClient consul; + private final String eventName; public ConsulSendingHandler(ConsulClient consul, String eventName) { @@ -42,16 +43,17 @@ public class ConsulSendingHandler extends AbstractMessageHandler { @Override protected void handleMessageInternal(Message message) throws Exception { - if (logger.isTraceEnabled()) { - logger.trace("Publishing message" + message); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Publishing message" + message); } Object payload = message.getPayload(); // TODO: support headers // TODO: support consul event filters: NodeFilter, ServiceFilter, TagFilter - Response event = consul.eventFire(this.eventName, (String) payload, + Response event = this.consul.eventFire(this.eventName, (String) payload, new EventParams(), QueryParams.DEFAULT); // TODO: return event? // return null; } + } diff --git a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/EventService.java b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/EventService.java index 7502c480..c6cf51f8 100644 --- a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/EventService.java +++ b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/EventService.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,6 @@ import java.util.concurrent.atomic.AtomicReference; import javax.annotation.PostConstruct; -import org.springframework.cloud.consul.binder.config.ConsulBinderProperties; - import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.QueryParams; import com.ecwid.consul.v1.Response; @@ -30,6 +28,8 @@ import com.ecwid.consul.v1.event.model.Event; import com.ecwid.consul.v1.event.model.EventParams; import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.cloud.consul.binder.config.ConsulBinderProperties; + /** * @author Spencer Gibb */ @@ -43,14 +43,15 @@ public class EventService { private AtomicReference lastIndex = new AtomicReference<>(); - public EventService(ConsulBinderProperties properties, ConsulClient consul, ObjectMapper objectMapper) { + public EventService(ConsulBinderProperties properties, ConsulClient consul, + ObjectMapper objectMapper) { this.properties = properties; this.consul = consul; this.objectMapper = objectMapper; } public ConsulClient getConsulClient() { - return consul; + return this.consul; } @PostConstruct @@ -58,25 +59,25 @@ public class EventService { setLastIndex(getEventsResponse()); } + public Long getLastIndex() { + return this.lastIndex.get(); + } + private void setLastIndex(Response response) { Long consulIndex = response.getConsulIndex(); if (consulIndex != null) { - lastIndex.set(response.getConsulIndex()); + this.lastIndex.set(response.getConsulIndex()); } } - public Long getLastIndex() { - return lastIndex.get(); - } - public Event fire(String name, String payload) { - Response response = consul.eventFire(name, payload, new EventParams(), + Response response = this.consul.eventFire(name, payload, new EventParams(), QueryParams.DEFAULT); return response.getValue(); } public Response> getEventsResponse() { - return consul.eventList(QueryParams.DEFAULT); + return this.consul.eventList(QueryParams.DEFAULT); } public List getEvents() { @@ -88,7 +89,7 @@ public class EventService { } public List watch() { - return watch(lastIndex.get()); + return watch(this.lastIndex.get()); } public List watch(Long lastIndex) { @@ -98,10 +99,11 @@ public class EventService { index = lastIndex; } int eventTimeout = 5; - if (properties != null) { - eventTimeout = properties.getEventTimeout(); + if (this.properties != null) { + eventTimeout = this.properties.getEventTimeout(); } - Response> watch = consul.eventList(new QueryParams(eventTimeout, index)); + Response> watch = this.consul + .eventList(new QueryParams(eventTimeout, index)); return filterEvents(readEvents(watch), lastIndex); } @@ -111,7 +113,10 @@ public class EventService { } /** - * from https://github.com/hashicorp/consul/blob/master/watch/funcs.go#L169-L194 + * from https://github.com/hashicorp/consul/blob/master/watch/funcs.go#L169-L194 . + * @param toFilter events to filter + * @param lastIndex last index to pick from the list of events + * @return filtered list of events */ protected List filterEvents(List toFilter, Long lastIndex) { List events = toFilter; diff --git a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfiguration.java b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfiguration.java index d4c95789..98c34d2d 100644 --- a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfiguration.java +++ b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,13 @@ package org.springframework.cloud.consul.binder.config; +import com.ecwid.consul.v1.ConsulClient; +import com.fasterxml.jackson.databind.ObjectMapper; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.consul.ConditionalOnConsulEnabled; import org.springframework.cloud.consul.binder.ConsulBinder; import org.springframework.cloud.consul.binder.EventService; @@ -29,9 +31,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import com.ecwid.consul.v1.ConsulClient; -import com.fasterxml.jackson.databind.ObjectMapper; - /** * Configures the Consul binder. * @@ -42,7 +41,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; @Import({ PropertyPlaceholderAutoConfiguration.class }) @ConditionalOnConsulEnabled @ConditionalOnProperty(name = "spring.cloud.consul.binder.enabled", matchIfMissing = true) -//FIXME: boot 2.0.0 @EnableConfigurationProperties({ConsulBinderProperties.class}) +// FIXME: boot 2.0.0 @EnableConfigurationProperties({ConsulBinderProperties.class}) public class ConsulBinderConfiguration { // @Autowired @@ -54,7 +53,8 @@ public class ConsulBinderConfiguration { @Bean @ConditionalOnMissingBean public EventService eventService(ConsulClient consulClient) { - return new EventService(null/*consulBinderProperties*/, consulClient, objectMapper); + return new EventService(null/* consulBinderProperties */, consulClient, + this.objectMapper); } @Bean @@ -63,5 +63,6 @@ public class ConsulBinderConfiguration { return new ConsulBinder(eventService); } - //TODO: create consul client if needed + // TODO: create consul client if needed + } diff --git a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderProperties.java b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderProperties.java index ee5988f3..d502acd5 100644 --- a/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderProperties.java +++ b/spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -24,6 +24,7 @@ import org.springframework.core.style.ToStringCreator; */ @ConfigurationProperties("spring.cloud.stream.consul.binder") public class ConsulBinderProperties { + private int eventTimeout = 5; public ConsulBinderProperties() { @@ -39,8 +40,8 @@ public class ConsulBinderProperties { @Override public String toString() { - return new ToStringCreator(this) - .append("eventTimeout", eventTimeout) + return new ToStringCreator(this).append("eventTimeout", this.eventTimeout) .toString(); } + } diff --git a/spring-cloud-consul-binder/src/main/resources/META-INF/spring-cloud-stream/consul-binder.properties b/spring-cloud-consul-binder/src/main/resources/META-INF/spring-cloud-stream/consul-binder.properties index db28478f..a912c091 100644 --- a/spring-cloud-consul-binder/src/main/resources/META-INF/spring-cloud-stream/consul-binder.properties +++ b/spring-cloud-consul-binder/src/main/resources/META-INF/spring-cloud-stream/consul-binder.properties @@ -13,6 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. # - spring.cloud.stream.binder.consul.default.host=localhost spring.cloud.stream.binder.consul.default.port=8500 diff --git a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulBinderApplicationTests.java b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulBinderApplicationTests.java index 7f20bf52..9da69779 100644 --- a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulBinderApplicationTests.java +++ b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulBinderApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,11 +18,14 @@ package org.springframework.cloud.consul.binder; import java.util.concurrent.TimeUnit; +import com.ecwid.consul.v1.ConsulClient; +import com.github.tomakehurst.wiremock.junit.WireMockRule; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -36,19 +39,17 @@ import org.springframework.messaging.support.MessageBuilder; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.github.tomakehurst.wiremock.junit.WireMockRule; - import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.put; import static com.github.tomakehurst.wiremock.client.WireMock.putRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; -import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD; + /** * @author Spencer Gibb */ @@ -56,33 +57,35 @@ import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER @SpringBootTest(classes = ConsulBinderApplicationTests.Application.class) @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) public class ConsulBinderApplicationTests { - @Autowired - private Events events; @Rule public final WireMockRule wireMock = new WireMockRule(18500); + @Autowired + private Events events; + @Before public void setUp() throws Exception { - wireMock.stubFor(put(urlPathMatching("/v1/event/fire/purchases")) + this.wireMock.stubFor(put(urlPathMatching("/v1/event/fire/purchases")) .willReturn(aResponse().withStatus(200))); - /*wireMock.stubFor(get(urlPathMatching("/v1/event/list")) - .willReturn(aResponse().withBody("[]") - .withStatus(200) - .withHeader("X-Consul-Index", "1")));*/ + /* + * wireMock.stubFor(get(urlPathMatching("/v1/event/list")) + * .willReturn(aResponse().withBody("[]") .withStatus(200) + * .withHeader("X-Consul-Index", "1"))); + */ } @Test - @Ignore //FIXME: 2.0.0 need stream fix + @Ignore // FIXME: 2.0.0 need stream fix public void shouldInitializeConsulSource() { - assertNotNull(events); + assertThat(this.events).isNotNull(); } @Test - @Ignore //FIXME: 2.0.0 need stream fix + @Ignore // FIXME: 2.0.0 need stream fix public void shouldPublishTextConsulMessage() { // given @@ -90,7 +93,7 @@ public class ConsulBinderApplicationTests { .build(); // when - events.purchases().send(message); + this.events.purchases().send(message); // then await().atMost(1, TimeUnit.SECONDS); @@ -101,12 +104,14 @@ public class ConsulBinderApplicationTests { @Output MessageChannel purchases(); + } @Configuration @EnableAutoConfiguration @EnableBinding(Events.class) public static class Application { + @Bean public ConsulClient consulClient() { return new ConsulClient("localhost", 18500); @@ -118,5 +123,7 @@ public class ConsulBinderApplicationTests { when(eventService.getConsulClient()).thenReturn(consulClient); return eventService; } + } + } diff --git a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulBinderTests.java b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulBinderTests.java index 1f434f1d..8997c67f 100644 --- a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulBinderTests.java +++ b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulBinderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2013-2019 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. @@ -27,6 +27,7 @@ import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.cloud.consul.binder.test.consumer.TestConsumer; import org.springframework.cloud.consul.binder.test.producer.TestProducer; import org.springframework.cloud.deployer.spi.app.AppDeployer; @@ -40,8 +41,7 @@ import org.springframework.util.SocketUtils; import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.RestTemplate; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link org.springframework.cloud.consul.binder.ConsulBinder}. @@ -49,12 +49,6 @@ import static org.junit.Assert.assertTrue; * @author Spencer Gibb */ public class ConsulBinderTests { - private static final Logger logger = LoggerFactory.getLogger(ConsulBinderTests.class); - - /** - * Timeout value in milliseconds for operations to complete. - */ - private static final long TIMEOUT = 30000; /** * Payload of test message. @@ -66,6 +60,13 @@ public class ConsulBinderTests { */ public static final String BINDING_NAME = "test"; + private static final Logger logger = LoggerFactory.getLogger(ConsulBinderTests.class); + + /** + * Timeout value in milliseconds for operations to complete. + */ + private static final long TIMEOUT = 30000; + /** * Deployer to launch producer and consumer test applications. */ @@ -76,7 +77,6 @@ public class ConsulBinderTests { */ private final RestTemplate restTemplate = new RestTemplate(); - public ConsulBinderTests() { LocalDeployerProperties properties = new LocalDeployerProperties(); properties.setDeleteFilesOnExit(false); @@ -85,43 +85,38 @@ public class ConsulBinderTests { /** * Test basic message sending functionality. - * - * @throws Exception + * @throws InterruptedException when waiting for message was interrupted */ @Test - @Ignore //FIXME: 2.0.0 need stream fix - public void testMessageSendReceive() throws Exception { + @Ignore // FIXME: 2.0.0 need stream fix + public void testMessageSendReceive() throws InterruptedException { testMessageSendReceive(null); } /** * Test usage of partition selector. - * * @throws Exception */ - /*@Test - public void testPartitionedMessageSendReceive() throws Exception { - testMessageSendReceive(null, true); - }*/ + /* + * @Test public void testPartitionedMessageSendReceive() throws Exception { + * testMessageSendReceive(null, true); } + */ /** * Test consumer group functionality. - * * @throws Exception */ - /*@Test - public void testMessageSendReceiveConsumerGroups() throws Exception { - testMessageSendReceive(new String[]{"a", "b"}, false); - }*/ + /* + * @Test public void testMessageSendReceiveConsumerGroups() throws Exception { + * testMessageSendReceive(new String[]{"a", "b"}, false); } + */ /** * Test message sending functionality. - * * @param groups consumer groups; may be {@code null} - * @param partitioned if true, execute test with a partition selector - * @throws Exception + * @throws InterruptedException when waiting for message was interrupted */ - private void testMessageSendReceive(String[] groups) throws Exception { + private void testMessageSendReceive(String[] groups) throws InterruptedException { Set consumers = null; AppId producer = null; @@ -130,7 +125,7 @@ public class ConsulBinderTests { producer = launchProducer(); for (AppId consumer : consumers) { - assertEquals(MESSAGE_PAYLOAD, waitForMessage(consumer.port)); + assertThat(waitForMessage(consumer.port)).isEqualTo(MESSAGE_PAYLOAD); } } finally { @@ -146,12 +141,11 @@ public class ConsulBinderTests { } /** - * Launch one or more consumers based on the number of consumer groups. - * Blocks execution until the consumers are bound. - * + * Launch one or more consumers based on the number of consumer groups. Blocks + * execution until the consumers are bound. * @param groups consumer groups; may be {@code null} * @return a set of {@link AppId}s for the consumers - * @throws InterruptedException + * @throws InterruptedException when waiting for message was interrupted */ private Set launchConsumers(String[] groups) throws InterruptedException { Set consumers = new HashSet<>(); @@ -170,7 +164,9 @@ public class ConsulBinderTests { if (groups != null) { args.add(String.format("--group=%s", groups[i])); } - consumers.add(new AppId(launchApplication(TestConsumer.class, appProperties, args), consumerPort)); + consumers.add( + new AppId(launchApplication(TestConsumer.class, appProperties, args), + consumerPort)); } for (AppId app : consumers) { waitForConsumer(app.port); @@ -181,7 +177,6 @@ public class ConsulBinderTests { /** * Launch a producer that publishes a test message. - * * @return {@link AppId} for producer */ private AppId launchProducer() { @@ -196,16 +191,16 @@ public class ConsulBinderTests { args.add(String.format("--partitioned=%b", false)); args.add("--debug"); - return new AppId(launchApplication(TestProducer.class, appProperties, args), producerPort); + return new AppId(launchApplication(TestProducer.class, appProperties, args), + producerPort); } /** * Block the executing thread until the consumer is bound. - * * @param port server port of the consumer application * @throws InterruptedException if the thread is interrupted - * @throws AssertionError if the consumer is not bound after - * {@value #TIMEOUT} milliseconds + * @throws AssertionError if the consumer is not bound after {@value #TIMEOUT} + * milliseconds */ private void waitForConsumer(int port) throws InterruptedException { long start = System.currentTimeMillis(); @@ -217,18 +212,17 @@ public class ConsulBinderTests { Thread.sleep(1000); } } - assertTrue("Consumer not bound", isConsumerBound(port)); + assertThat(isConsumerBound(port)).as("Consumer not bound").isTrue(); } /** * Return {@code true} if the consumer at the provided port is bound. - * * @param port http port for consumer * @return true if consumer is bound */ private boolean isConsumerBound(int port) { try { - return restTemplate.getForObject( + return this.restTemplate.getForObject( String.format("http://localhost:%d/is-bound", port), Boolean.class); } catch (ResourceAccessException e) { @@ -239,15 +233,14 @@ public class ConsulBinderTests { /** * Return the most recent payload message a consumer received. - * * @param port http port for consumer - * @return the most recent payload message a consumer received; - * may be {@code null} + * @return the most recent payload message a consumer received; may be {@code null} */ private String getConsumerMessagePayload(int port) { try { - return restTemplate.getForObject( - String.format("http://localhost:%d/message-payload", port), String.class); + return this.restTemplate.getForObject( + String.format("http://localhost:%d/message-payload", port), + String.class); } catch (ResourceAccessException e) { logger.debug("getConsumerMessagePayload", e); @@ -257,13 +250,12 @@ public class ConsulBinderTests { /** * Return {@code true} if the producer made use of a custom partition selector. - * * @param port http port for producer * @return true if the producer used a custom partition selector */ - private boolean partitionSelectorUsed(int port) throws InterruptedException { + private boolean partitionSelectorUsed(int port) { try { - return restTemplate.getForObject( + return this.restTemplate.getForObject( String.format("http://localhost:%d/partition-strategy-invoked", port), Boolean.class); } @@ -274,9 +266,8 @@ public class ConsulBinderTests { } /** - * Block the executing thread until a message is received by the - * consumer application, or until {@value #TIMEOUT} milliseconds elapses. - * + * Block the executing thread until a message is received by the consumer application, + * or until {@value #TIMEOUT} milliseconds elapses. * @param port server port of the consumer application * @return the message payload that was received * @throws InterruptedException if the thread is interrupted @@ -298,29 +289,31 @@ public class ConsulBinderTests { /** * Launch an application in a separate JVM. - * * @param clz the main class to launch * @param properties the properties to pass to the application * @param args the command line arguments for the application * @return a string identifier for the application */ - private String launchApplication(Class clz, Map properties, List args) { - Resource resource = new UrlResource(clz.getProtectionDomain().getCodeSource().getLocation()); + private String launchApplication(Class clz, Map properties, + List args) { + Resource resource = new UrlResource( + clz.getProtectionDomain().getCodeSource().getLocation()); properties.put(AppDeployer.GROUP_PROPERTY_KEY, "test-group"); properties.put("main", clz.getName()); properties.put("classpath", System.getProperty("java.class.path")); - String appName = String.format("%s-%s", clz.getSimpleName(), properties.get("server.port")); + String appName = String.format("%s-%s", clz.getSimpleName(), + properties.get("server.port")); AppDefinition definition = new AppDefinition(appName, properties); - AppDeploymentRequest request = new AppDeploymentRequest(definition, resource, properties, args); + AppDeploymentRequest request = new AppDeploymentRequest(definition, resource, + properties, args); return this.deployer.deploy(request); } /** * Shut down the application with the provided id. - * * @param id id of application to shut down */ private void shutdownApplication(String id) { @@ -331,7 +324,6 @@ public class ConsulBinderTests { /** * Instantiates a new local app deployer. - * * @param properties the properties */ ClasspathDeployer(LocalDeployerProperties properties) { @@ -340,12 +332,12 @@ public class ConsulBinderTests { /** * Builds the jar execution command. - * * @param jarPath the jar path * @param request the request * @return the string[] */ - protected String[] buildJarExecutionCommand(String jarPath, AppDeploymentRequest request) { + protected String[] buildJarExecutionCommand(String jarPath, + AppDeploymentRequest request) { ArrayList commands = new ArrayList<>(); commands.add(super.getLocalDeployerProperties().getJavaCmd()); @@ -356,14 +348,16 @@ public class ConsulBinderTests { return commands.toArray(new String[commands.size()]); } - } + } /** * String identification and http port for a launched application. */ private static class AppId { + final String id; + final int port; AppId(String id, int port) { @@ -381,15 +375,16 @@ public class ConsulBinderTests { } AppId appId = (AppId) o; - return port == appId.port && id.equals(appId.id); + return this.port == appId.port && this.id.equals(appId.id); } @Override public int hashCode() { - int result = id.hashCode(); - result = 31 * result + port; + int result = this.id.hashCode(); + result = 31 * result + this.port; return result; } + } } diff --git a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducerTests.java b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducerTests.java index b9d78d0d..6a6f1917 100644 --- a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducerTests.java +++ b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,10 @@ package org.springframework.cloud.consul.binder; +import com.ecwid.consul.v1.OperationException; import org.junit.Test; -import com.ecwid.consul.v1.OperationException; - -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -34,15 +33,16 @@ public class ConsulInboundMessageProducerTests { EventService eventService = mock(EventService.class); when(eventService.watch()).thenThrow(new OperationException(500, "error", "")); - ConsulInboundMessageProducer producer = new ConsulInboundMessageProducer(eventService); + ConsulInboundMessageProducer producer = new ConsulInboundMessageProducer( + eventService); try { producer.getEvents(); - } catch (Exception e) { - fail("ConsulInboundMessageProducer threw unexpected exception: "+e); + } + catch (Exception e) { + fail("ConsulInboundMessageProducer threw unexpected exception: " + e); } } - } diff --git a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfigurationTests.java b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfigurationTests.java index b6ad2380..9b377f56 100644 --- a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfigurationTests.java +++ b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.stream.annotation.EnableBinding; @@ -38,31 +39,33 @@ public class ConsulBinderConfigurationTests { public ExpectedException exception = ExpectedException.none(); @Test - @Ignore //FIXME 2.0.0 need stream fix + @Ignore // FIXME 2.0.0 need stream fix public void consulBinderDisabledWorks() { this.exception.expectMessage(containsString("no proper implementation found")); new SpringApplicationBuilder(Application.class) - .properties("spring.cloud.consul.binder.enabled=false") - .run(); + .properties("spring.cloud.consul.binder.enabled=false").run(); } @Test - @Ignore //FIXME 2.0.0 need stream fix + @Ignore // FIXME 2.0.0 need stream fix public void consulDisabledDisablesBinder() { this.exception.expectMessage(containsString("no proper implementation found")); new SpringApplicationBuilder(Application.class) - .properties("spring.cloud.consul.enabled=false") - .run(); + .properties("spring.cloud.consul.enabled=false").run(); } interface Events { + @Output MessageChannel purchases(); + } @Configuration @EnableAutoConfiguration @EnableBinding(Events.class) public static class Application { + } + } diff --git a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/test/consumer/TestConsumer.java b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/test/consumer/TestConsumer.java index 11e3a48b..5cdf5300 100644 --- a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/test/consumer/TestConsumer.java +++ b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/test/consumer/TestConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,6 +18,7 @@ package org.springframework.cloud.consul.binder.test.consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; @@ -27,7 +28,6 @@ import org.springframework.cloud.consul.binder.ConsulBinder; import org.springframework.cloud.consul.binder.ConsulBinderTests; import org.springframework.cloud.consul.binder.config.ConsulBinderConfiguration; import org.springframework.cloud.stream.binder.ConsumerProperties; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.messaging.Message; @@ -39,14 +39,15 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** - * Consumer application that binds a channel to a {@link ConsulBinder} - * and stores the received message payload. + * Consumer application that binds a channel to a {@link ConsulBinder} and stores the + * received message payload. */ @RestController @Import(ConsulBinderConfiguration.class) @Configuration @EnableAutoConfiguration public class TestConsumer implements ApplicationRunner { + private static final Logger logger = LoggerFactory.getLogger(TestConsumer.class); /** @@ -64,23 +65,21 @@ public class TestConsumer implements ApplicationRunner { /** * Main method. - * * @param args if present, first arg is consumer group name - * @throws Exception */ - public static void main(String[] args) throws Exception { + public static void main(String[] args) { SpringApplication.run(TestConsumer.class, args); } @Override public void run(ApplicationArguments args) throws Exception { - logger.info("Consumer running with binder {}", binder); + logger.info("Consumer running with binder {}", this.binder); SubscribableChannel consumerChannel = new ExecutorSubscribableChannel(); consumerChannel.subscribe(new MessageHandler() { @Override public void handleMessage(Message message) throws MessagingException { - messagePayload = (String) message.getPayload(); - logger.info("Received message: {}", messagePayload); + TestConsumer.this.messagePayload = (String) message.getPayload(); + logger.info("Received message: {}", TestConsumer.this.messagePayload); } }); String group = null; @@ -89,19 +88,19 @@ public class TestConsumer implements ApplicationRunner { group = args.getOptionValues("group").get(0); } - binder.bindConsumer(ConsulBinderTests.BINDING_NAME, group, consumerChannel, + this.binder.bindConsumer(ConsulBinderTests.BINDING_NAME, group, consumerChannel, new ConsumerProperties()); - isBound = true; + this.isBound = true; } @RequestMapping("/is-bound") public boolean isBound() { - return isBound; + return this.isBound; } @RequestMapping("/message-payload") public String getMessagePayload() { - return messagePayload; + return this.messagePayload; } } diff --git a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/test/producer/TestProducer.java b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/test/producer/TestProducer.java index c3b79323..06c04f5f 100644 --- a/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/test/producer/TestProducer.java +++ b/spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/test/producer/TestProducer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,6 +18,7 @@ package org.springframework.cloud.consul.binder.test.producer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; @@ -40,8 +41,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** - * Producer application that binds a channel to a {@link ConsulBinder} - * and sends a test message. + * Producer application that binds a channel to a {@link ConsulBinder} and sends a test + * message. */ @RestController @Import(ConsulBinderConfiguration.class) @@ -60,17 +61,20 @@ public class TestProducer implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { - /*if (args.containsOption("partitioned") - && Boolean.valueOf(args.getOptionValues("partitioned").get(0))) { - binder.setPartitionSelector(stubPartitionSelectorStrategy()); - }*/ + /* + * if (args.containsOption("partitioned") && + * Boolean.valueOf(args.getOptionValues("partitioned").get(0))) { + * binder.setPartitionSelector(stubPartitionSelectorStrategy()); } + */ SubscribableChannel producerChannel = producerChannel(); ProducerProperties properties = new ProducerProperties(); - properties.setPartitionKeyExpression(new SpelExpressionParser().parseExpression("payload")); - binder.bindProducer(ConsulBinderTests.BINDING_NAME, producerChannel, properties); + properties.setPartitionKeyExpression( + new SpelExpressionParser().parseExpression("payload")); + this.binder.bindProducer(ConsulBinderTests.BINDING_NAME, producerChannel, + properties); Message message = new GenericMessage<>(ConsulBinderTests.MESSAGE_PAYLOAD); - logger.info("Writing message to binder {}", binder); + logger.info("Writing message to binder {}", this.binder); producerChannel.send(message); } @@ -89,16 +93,19 @@ public class TestProducer implements ApplicationRunner { return stubPartitionSelectorStrategy().invoked; } + public static class StubPartitionSelectorStrategy + implements PartitionSelectorStrategy { - public static class StubPartitionSelectorStrategy implements PartitionSelectorStrategy { public volatile boolean invoked = false; @Override public int selectPartition(Object key, int partitionCount) { - logger.info("Selecting partition for key {}; partition count: {}", key, partitionCount); - invoked = true; + logger.info("Selecting partition for key {}; partition count: {}", key, + partitionCount); + this.invoked = true; return 1; } + } } diff --git a/spring-cloud-consul-binder/src/test/resources/application.yml b/spring-cloud-consul-binder/src/test/resources/application.yml index 7d8396c0..0c1f35a9 100644 --- a/spring-cloud-consul-binder/src/test/resources/application.yml +++ b/spring-cloud-consul-binder/src/test/resources/application.yml @@ -1,4 +1,3 @@ - spring: cloud: stream: diff --git a/spring-cloud-consul-config/pom.xml b/spring-cloud-consul-config/pom.xml index 72be559b..3186697d 100644 --- a/spring-cloud-consul-config/pom.xml +++ b/spring-cloud-consul-config/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConfigWatch.java b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConfigWatch.java index 74b854f9..471513ce 100644 --- a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConfigWatch.java +++ b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConfigWatch.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,17 +50,33 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc private static final Log log = LogFactory.getLog(ConfigWatch.class); private final ConsulConfigProperties properties; + private final ConsulClient consul; - private LinkedHashMap consulIndexes; + private final TaskScheduler taskScheduler; + private final AtomicBoolean running = new AtomicBoolean(false); + + private LinkedHashMap consulIndexes; + private ApplicationEventPublisher publisher; + private boolean firstTime = true; + private ScheduledFuture watchFuture; - public ConfigWatch(ConsulConfigProperties properties, ConsulClient consul, LinkedHashMap initialIndexes) { + public ConfigWatch(ConsulConfigProperties properties, ConsulClient consul, + LinkedHashMap initialIndexes) { this(properties, consul, initialIndexes, getTaskScheduler()); - } + } + + public ConfigWatch(ConsulConfigProperties properties, ConsulClient consul, + LinkedHashMap initialIndexes, TaskScheduler taskScheduler) { + this.properties = properties; + this.consul = consul; + this.consulIndexes = new LinkedHashMap<>(initialIndexes); + this.taskScheduler = taskScheduler; + } private static ThreadPoolTaskScheduler getTaskScheduler() { ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); @@ -68,14 +84,6 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc return taskScheduler; } - public ConfigWatch(ConsulConfigProperties properties, ConsulClient consul, LinkedHashMap initialIndexes, - TaskScheduler taskScheduler) { - this.properties = properties; - this.consul = consul; - this.consulIndexes = new LinkedHashMap<>(initialIndexes); - this.taskScheduler = taskScheduler; - } - @Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; @@ -84,8 +92,8 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc @Override public void start() { if (this.running.compareAndSet(false, true)) { - this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(this::watchConfigKeyValues, - this.properties.getWatch().getDelay()); + this.watchFuture = this.taskScheduler.scheduleWithFixedDelay( + this::watchConfigKeyValues, this.properties.getWatch().getDelay()); } } @@ -117,13 +125,14 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc return this.running.get(); } - @Timed(value ="consul.watch-config-keys") + @Timed("consul.watch-config-keys") public void watchConfigKeyValues() { if (this.running.get()) { for (String context : this.consulIndexes.keySet()) { - // turn the context into a Consul folder path (unless our config format are FILES) - if (properties.getFormat() != FILES && !context.endsWith("/")) { + // turn the context into a Consul folder path (unless our config format + // are FILES) + if (this.properties.getFormat() != FILES && !context.endsWith("/")) { context = context + "/"; } @@ -133,63 +142,85 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc currentIndex = -1L; } - log.trace("watching consul for context '"+context+"' with index "+ currentIndex); + log.trace("watching consul for context '" + context + "' with index " + + currentIndex); // use the consul ACL token if found - String aclToken = properties.getAclToken(); + String aclToken = this.properties.getAclToken(); if (StringUtils.isEmpty(aclToken)) { - aclToken = null; + aclToken = null; } - Response> response = this.consul.getKVValues(context, aclToken, + Response> response = this.consul.getKVValues(context, + aclToken, new QueryParams(this.properties.getWatch().getWaitTime(), currentIndex)); - // if response.value == null, response was a 404, otherwise it was a 200 + // if response.value == null, response was a 404, otherwise it was a + // 200 // reducing churn if there wasn't anything if (response.getValue() != null && !response.getValue().isEmpty()) { Long newIndex = response.getConsulIndex(); if (newIndex != null && !newIndex.equals(currentIndex)) { - // don't publish the same index again, don't publish the first time (-1) so index can be primed - if (!this.consulIndexes.containsValue(newIndex) && !currentIndex.equals(-1L)) { - log.trace("Context "+context + " has new index " + newIndex); - RefreshEventData data = new RefreshEventData(context, currentIndex, newIndex); - this.publisher.publishEvent(new RefreshEvent(this, data, data.toString())); - } else if (log.isTraceEnabled()) { - log.trace("Event for index already published for context "+context); + // don't publish the same index again, don't publish the first + // time (-1) so index can be primed + if (!this.consulIndexes.containsValue(newIndex) + && !currentIndex.equals(-1L)) { + log.trace("Context " + context + " has new index " + + newIndex); + RefreshEventData data = new RefreshEventData(context, + currentIndex, newIndex); + this.publisher.publishEvent( + new RefreshEvent(this, data, data.toString())); + } + else if (log.isTraceEnabled()) { + log.trace("Event for index already published for context " + + context); } this.consulIndexes.put(context, newIndex); - } else if (log.isTraceEnabled()) { - log.trace("Same index for context "+context); } - } else if (log.isTraceEnabled()) { - log.trace("No value for context "+context); + else if (log.isTraceEnabled()) { + log.trace("Same index for context " + context); + } + } + else if (log.isTraceEnabled()) { + log.trace("No value for context " + context); } - } catch (Exception e) { + } + catch (Exception e) { // only fail fast on the initial query, otherwise just log the error - if (firstTime && this.properties.isFailFast()) { - log.error("Fail fast is set and there was an error reading configuration from consul."); + if (this.firstTime && this.properties.isFailFast()) { + log.error( + "Fail fast is set and there was an error reading configuration from consul."); ReflectionUtils.rethrowRuntimeException(e); - } else if (log.isTraceEnabled()) { - log.trace("Error querying consul Key/Values for context '" + context + "'", e); - } else if (log.isWarnEnabled()) { - // simplified one line log message in the event of an agent failure - log.warn("Error querying consul Key/Values for context '" + context + "'. Message: " + e.getMessage()); + } + else if (log.isTraceEnabled()) { + log.trace("Error querying consul Key/Values for context '" + + context + "'", e); + } + else if (log.isWarnEnabled()) { + // simplified one line log message in the event of an agent + // failure + log.warn("Error querying consul Key/Values for context '" + + context + "'. Message: " + e.getMessage()); } } } } - firstTime = false; + this.firstTime = false; } static class RefreshEventData { + private final String context; + private final Long prevIndex; + private final Long newIndex; - public RefreshEventData(String context, Long prevIndex, Long newIndex) { + RefreshEventData(String context, Long prevIndex, Long newIndex) { this.context = context; this.prevIndex = prevIndex; this.newIndex = newIndex; @@ -209,26 +240,30 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } RefreshEventData that = (RefreshEventData) o; - return Objects.equals(context, that.context) && - Objects.equals(prevIndex, that.prevIndex) && - Objects.equals(newIndex, that.newIndex); + return Objects.equals(this.context, that.context) + && Objects.equals(this.prevIndex, that.prevIndex) + && Objects.equals(this.newIndex, that.newIndex); } @Override public int hashCode() { - return Objects.hash(context, prevIndex, newIndex); + return Objects.hash(this.context, this.prevIndex, this.newIndex); } @Override public String toString() { - return new ToStringCreator(this) - .append("context", context) - .append("prevIndex", prevIndex) - .append("newIndex", newIndex) + return new ToStringCreator(this).append("context", this.context) + .append("prevIndex", this.prevIndex).append("newIndex", this.newIndex) .toString(); } + } + } diff --git a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigAutoConfiguration.java b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigAutoConfiguration.java index 9bdc113b..0e10ecdd 100644 --- a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigAutoConfiguration.java +++ b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -36,23 +36,30 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; @ConditionalOnProperty(name = "spring.cloud.consul.config.enabled", matchIfMissing = true) public class ConsulConfigAutoConfiguration { + /** + * Name of the config watch task scheduler bean. + */ public static final String CONFIG_WATCH_TASK_SCHEDULER_NAME = "configWatchTaskScheduler"; @Configuration @ConditionalOnClass(RefreshEndpoint.class) protected static class ConsulRefreshConfiguration { + @Bean @ConditionalOnProperty(name = "spring.cloud.consul.config.watch.enabled", matchIfMissing = true) public ConfigWatch configWatch(ConsulConfigProperties properties, ConsulPropertySourceLocator locator, ConsulClient consul, - @Qualifier(CONFIG_WATCH_TASK_SCHEDULER_NAME) TaskScheduler taskScheduler) { - return new ConfigWatch(properties, consul, locator.getContextIndexes(), taskScheduler); + @Qualifier(CONFIG_WATCH_TASK_SCHEDULER_NAME) TaskScheduler taskScheduler) { + return new ConfigWatch(properties, consul, locator.getContextIndexes(), + taskScheduler); } @Bean(name = CONFIG_WATCH_TASK_SCHEDULER_NAME) @ConditionalOnProperty(name = "spring.cloud.consul.config.watch.enabled", matchIfMissing = true) - public TaskScheduler configWatchTaskScheduler() { + public TaskScheduler configWatchTaskScheduler() { return new ThreadPoolTaskScheduler(); } + } + } diff --git a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfiguration.java b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfiguration.java index d0a348b4..92706641 100644 --- a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfiguration.java +++ b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -19,8 +19,8 @@ package org.springframework.cloud.consul.config; import com.ecwid.consul.v1.ConsulClient; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.consul.ConditionalOnConsulEnabled; import org.springframework.cloud.consul.ConsulAutoConfiguration; @@ -41,6 +41,7 @@ public class ConsulConfigBootstrapConfiguration { @Import(ConsulAutoConfiguration.class) @ConditionalOnProperty(name = "spring.cloud.consul.config.enabled", matchIfMissing = true) protected static class ConsulPropertySourceConfiguration { + @Autowired private ConsulClient consul; @@ -53,7 +54,9 @@ public class ConsulConfigBootstrapConfiguration { @Bean public ConsulPropertySourceLocator consulPropertySourceLocator( ConsulConfigProperties consulConfigProperties) { - return new ConsulPropertySourceLocator(consul, consulConfigProperties); + return new ConsulPropertySourceLocator(this.consul, consulConfigProperties); } + } + } diff --git a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigProperties.java b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigProperties.java index d1f21ae7..b4d91c26 100644 --- a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigProperties.java +++ b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,22 @@ package org.springframework.cloud.consul.config; +import javax.annotation.PostConstruct; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.style.ToStringCreator; import org.springframework.validation.annotation.Validated; -import javax.annotation.PostConstruct; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - /** * @author Spencer Gibb */ @ConfigurationProperties("spring.cloud.consul.config") @Validated public class ConsulConfigProperties { + private boolean enabled = true; private String prefix = "config"; @@ -45,8 +46,8 @@ public class ConsulConfigProperties { private Format format = Format.KEY_VALUE; /** - * If format is Format.PROPERTIES or Format.YAML - * then the following field is used as key to look up consul for configuration. + * If format is Format.PROPERTIES or Format.YAML then the following field is used as + * key to look up consul for configuration. */ @NotEmpty private String dataKey = "data"; @@ -80,103 +81,154 @@ public class ConsulConfigProperties { return this.enabled; } - public String getPrefix() { - return this.prefix; - } - - public @NotEmpty String getDefaultContext() { - return this.defaultContext; - } - - public @NotEmpty String getProfileSeparator() { - return this.profileSeparator; - } - - public @NotNull Format getFormat() { - return this.format; - } - - public @NotEmpty String getDataKey() { - return this.dataKey; - } - - public String getAclToken() { - return this.aclToken; - } - - public Watch getWatch() { - return this.watch; - } - - public boolean isFailFast() { - return this.failFast; - } - - public String getName() { - return this.name; - } - public void setEnabled(boolean enabled) { this.enabled = enabled; } + public String getPrefix() { + return this.prefix; + } + public void setPrefix(String prefix) { this.prefix = prefix; } + public @NotEmpty String getDefaultContext() { + return this.defaultContext; + } + public void setDefaultContext(@NotEmpty String defaultContext) { this.defaultContext = defaultContext; } + public @NotEmpty String getProfileSeparator() { + return this.profileSeparator; + } + public void setProfileSeparator(@NotEmpty String profileSeparator) { this.profileSeparator = profileSeparator; } + public @NotNull Format getFormat() { + return this.format; + } + public void setFormat(@NotNull Format format) { this.format = format; } + public @NotEmpty String getDataKey() { + return this.dataKey; + } + public void setDataKey(@NotEmpty String dataKey) { this.dataKey = dataKey; } + public String getAclToken() { + return this.aclToken; + } + public void setAclToken(String aclToken) { this.aclToken = aclToken; } + public Watch getWatch() { + return this.watch; + } + public void setWatch(Watch watch) { this.watch = watch; } + public boolean isFailFast() { + return this.failFast; + } + public void setFailFast(boolean failFast) { this.failFast = failFast; } + public String getName() { + return this.name; + } + public void setName(String name) { this.name = name; } @Override public String toString() { - return new ToStringCreator(this) - .append("enabled", enabled) - .append("prefix", prefix) - .append("defaultContext", defaultContext) - .append("profileSeparator", profileSeparator) - .append("format", format) - .append("dataKey", dataKey) - .append("aclToken", aclToken) - .append("watch", watch) - .append("failFast", failFast) - .append("name", name) - .toString(); + return new ToStringCreator(this).append("enabled", this.enabled) + .append("prefix", this.prefix) + .append("defaultContext", this.defaultContext) + .append("profileSeparator", this.profileSeparator) + .append("format", this.format).append("dataKey", this.dataKey) + .append("aclToken", this.aclToken).append("watch", this.watch) + .append("failFast", this.failFast).append("name", this.name).toString(); } + /** + * There are many ways in which we can specify configuration in consul i.e., + * + *
    + *
  1. Nested key value style: Where value is either a constant or part of the key + * (nested). For e.g., For following configuration a.b.c=something a.b.d=something + * else One can specify the configuration in consul with key as + * "../kv/config/application/a/b/c" and value as "something" and key as + * "../kv/config/application/a/b/d" and value as "something else"
  2. + *
  3. Entire contents of properties file as value For e.g., For following + * configuration a.b.c=something a.b.d=something else One can specify the + * configuration in consul with key as "../kv/config/application/properties" and value + * as whole configuration " a.b.c=something a.b.d=something else "
  4. + *
  5. as Json or YML. You get it.
  6. + *
+ * + * This enum specifies the different Formats/styles supported for loading the + * configuration. + * + * @author srikalyan.swayampakula + */ + public enum Format { + + /** + * Indicates that the configuration specified in consul is of type native key + * values. + */ + KEY_VALUE, + + /** + * Indicates that the configuration specified in consul is of property style i.e., + * value of the consul key would be a list of key=value pairs separated by new + * lines. + */ + PROPERTIES, + + /** + * Indicates that the configuration specified in consul is of YAML style i.e., + * value of the consul key would be YAML format. + */ + YAML, + + /** + * Indicates that the configuration specified in consul uses keys as files. This + * is useful for tools like git2consul. + */ + FILES, + + } + + /** + * Consul watch properties. + */ public static class Watch { - /** The number of seconds to wait (or block) for watch query, defaults to 55. - * Needs to be less than default ConsulClient (defaults to 60). To increase ConsulClient + + /** + * The number of seconds to wait (or block) for watch query, defaults to 55. Needs + * to be less than default ConsulClient (defaults to 60). To increase ConsulClient * timeout create a ConsulClient bean with a custom ConsulRawClient with a custom - * HttpClient. */ + * HttpClient. + */ private int waitTime = 55; /** If the watch is enabled. Defaults to true. */ @@ -192,83 +244,33 @@ public class ConsulConfigProperties { return this.waitTime; } - public boolean isEnabled() { - return this.enabled; - } - - public int getDelay() { - return this.delay; - } - public void setWaitTime(int waitTime) { this.waitTime = waitTime; } + public boolean isEnabled() { + return this.enabled; + } + public void setEnabled(boolean enabled) { this.enabled = enabled; } + public int getDelay() { + return this.delay; + } + public void setDelay(int delay) { this.delay = delay; } @Override public String toString() { - return new ToStringCreator(this) - .append("waitTime", waitTime) - .append("enabled", enabled) - .append("delay", delay) + return new ToStringCreator(this).append("waitTime", this.waitTime) + .append("enabled", this.enabled).append("delay", this.delay) .toString(); } - } - - /** - * There are many ways in which we can specify configuration in consul i.e., - * - *
    - *
  1. - * Nested key value style: Where value is either a constant or part of the key (nested). - * For e.g., For following configuration a.b.c=something a.b.d=something else One can - * specify the configuration in consul with key as "../kv/config/application/a/b/c" and - * value as "something" and key as "../kv/config/application/a/b/d" and value as - * "something else"
  2. - *
  3. - * Entire contents of properties file as value For e.g., For following configuration - * a.b.c=something a.b.d=something else One can specify the configuration in consul with - * key as "../kv/config/application/properties" and value as whole configuration " - * a.b.c=something a.b.d=something else "
  4. - *
  5. - * as Json or YML. You get it.
  6. - *
- * - * This enum specifies the different Formats/styles supported for loading the - * configuration. - * - * @author srikalyan.swayampakula - */ - public enum Format { - /** - * Indicates that the configuration specified in consul is of type native key values. - */ - KEY_VALUE, - - /** - * Indicates that the configuration specified in consul is of property style i.e., - * value of the consul key would be a list of key=value pairs separated by new lines. - */ - PROPERTIES, - - /** - * Indicates that the configuration specified in consul is of YAML style i.e., value - * of the consul key would be YAML format - */ - YAML, - - /** - * Indicates that the configuration specified in consul uses keys as files. - * This is useful for tools like git2consul. - */ - FILES, } + } diff --git a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulFilesPropertySource.java b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulFilesPropertySource.java index 57593091..f297ba25 100644 --- a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulFilesPropertySource.java +++ b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulFilesPropertySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -26,22 +26,28 @@ import static org.springframework.cloud.consul.config.ConsulConfigProperties.For * @author Spencer Gibb */ public class ConsulFilesPropertySource extends ConsulPropertySource { - public ConsulFilesPropertySource(String context, ConsulClient source, ConsulConfigProperties configProperties) { + + public ConsulFilesPropertySource(String context, ConsulClient source, + ConsulConfigProperties configProperties) { super(context, source, configProperties); } @Override public void init() { - //noop + // noop } public void init(GetValue value) { if (this.getContext().endsWith(".yml") || this.getContext().endsWith(".yaml")) { parseValue(value, YAML); - } else if (this.getContext().endsWith(".properties")) { + } + else if (this.getContext().endsWith(".properties")) { parseValue(value, PROPERTIES); - } else { - throw new IllegalStateException("Unknown files extension for context " + this.getContext()); + } + else { + throw new IllegalStateException( + "Unknown files extension for context " + this.getContext()); } } + } diff --git a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulPropertySource.java b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulPropertySource.java index 176c8181..91612ac3 100644 --- a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulPropertySource.java +++ b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulPropertySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -24,16 +24,16 @@ import java.util.Map; import java.util.Properties; import java.util.Set; -import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.util.StringUtils; - import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.QueryParams; import com.ecwid.consul.v1.Response; import com.ecwid.consul.v1.kv.model.GetValue; +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.env.EnumerablePropertySource; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.util.StringUtils; + import static org.springframework.cloud.consul.config.ConsulConfigProperties.Format.PROPERTIES; import static org.springframework.cloud.consul.config.ConsulConfigProperties.Format.YAML; import static org.springframework.util.Base64Utils.decodeFromString; @@ -43,11 +43,12 @@ import static org.springframework.util.Base64Utils.decodeFromString; */ public class ConsulPropertySource extends EnumerablePropertySource { - private String context; - private ConsulConfigProperties configProperties; - private final Map properties = new LinkedHashMap<>(); + private String context; + + private ConsulConfigProperties configProperties; + private Long initialIndex; public ConsulPropertySource(String context, ConsulClient source, @@ -63,13 +64,13 @@ public class ConsulPropertySource extends EnumerablePropertySource this.context = this.context + "/"; } - Response> response = source.getKVValues(context, - configProperties.getAclToken(), QueryParams.DEFAULT); + Response> response = this.source.getKVValues(this.context, + this.configProperties.getAclToken(), QueryParams.DEFAULT); - initialIndex = response.getConsulIndex(); + this.initialIndex = response.getConsulIndex(); final List values = response.getValue(); - ConsulConfigProperties.Format format = configProperties.getFormat(); + ConsulConfigProperties.Format format = this.configProperties.getFormat(); switch (format) { case KEY_VALUE: parsePropertiesInKeyValueFormat(values); @@ -81,14 +82,13 @@ public class ConsulPropertySource extends EnumerablePropertySource } public Long getInitialIndex() { - return initialIndex; + return this.initialIndex; } /** * Parses the properties in key value style i.e., values are expected to be either a - * sub key or a constant - * - * @param values + * sub key or a constant. + * @param values values to parse */ protected void parsePropertiesInKeyValueFormat(List values) { if (values == null) { @@ -98,18 +98,18 @@ public class ConsulPropertySource extends EnumerablePropertySource for (GetValue getValue : values) { String key = getValue.getKey(); if (!StringUtils.endsWithIgnoreCase(key, "/")) { - key = key.replace(context, "").replace('/', '.'); + key = key.replace(this.context, "").replace('/', '.'); String value = getValue.getDecodedValue(); - properties.put(key, value); + this.properties.put(key, value); } } } /** * Parses the properties using the format which is not a key value style i.e., either - * java properties style or YAML style - * - * @param values + * java properties style or YAML style. + * @param values values to parse + * @param format format in which the values should be parsed */ protected void parsePropertiesWithNonKeyValueFormat(List values, ConsulConfigProperties.Format format) { @@ -118,8 +118,8 @@ public class ConsulPropertySource extends EnumerablePropertySource } for (GetValue getValue : values) { - String key = getValue.getKey().replace(context, ""); - if (configProperties.getDataKey().equals(key)) { + String key = getValue.getKey().replace(this.context, ""); + if (this.configProperties.getDataKey().equals(key)) { parseValue(getValue, format); } } @@ -134,8 +134,7 @@ public class ConsulPropertySource extends EnumerablePropertySource Properties props = generateProperties(value, format); for (Map.Entry entry : props.entrySet()) { - properties - .put(entry.getKey().toString(), entry.getValue()); + this.properties.put(entry.getKey().toString(), entry.getValue()); } } @@ -150,8 +149,8 @@ public class ConsulPropertySource extends EnumerablePropertySource props.load(new ByteArrayInputStream(value.getBytes("ISO-8859-1"))); } catch (IOException e) { - throw new IllegalArgumentException(value - + " can't be encoded using ISO-8859-1"); + throw new IllegalArgumentException( + value + " can't be encoded using ISO-8859-1"); } return props; @@ -168,34 +167,38 @@ public class ConsulPropertySource extends EnumerablePropertySource /** * @deprecated As of 1.1.0 use {@link GetValue#getDecodedValue()}. + * @param value encoded value + * @return the decoded string */ @Deprecated public String getDecoded(String value) { - if (value == null) + if (value == null) { return null; + } return new String(decodeFromString(value)); } protected Map getProperties() { - return properties; + return this.properties; } protected ConsulConfigProperties getConfigProperties() { - return configProperties; + return this.configProperties; } protected String getContext() { - return context; + return this.context; } @Override public Object getProperty(String name) { - return properties.get(name); + return this.properties.get(name); } @Override public String[] getPropertyNames() { - Set strings = properties.keySet(); + Set strings = this.properties.keySet(); return strings.toArray(new String[strings.size()]); } + } diff --git a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocator.java b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocator.java index d9848de5..142f28f3 100644 --- a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocator.java +++ b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -48,6 +48,7 @@ import static org.springframework.cloud.consul.config.ConsulConfigProperties.For public class ConsulPropertySourceLocator implements PropertySourceLocator { private static final Log log = LogFactory.getLog(ConsulPropertySourceLocator.class); + private final ConsulClient consul; private final ConsulConfigProperties properties; @@ -56,18 +57,19 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator { private final LinkedHashMap contextIndex = new LinkedHashMap<>(); - public ConsulPropertySourceLocator(ConsulClient consul, ConsulConfigProperties properties) { + public ConsulPropertySourceLocator(ConsulClient consul, + ConsulConfigProperties properties) { this.consul = consul; this.properties = properties; } @Deprecated public List getContexts() { - return contexts; + return this.contexts; } public LinkedHashMap getContextIndexes() { - return contextIndex; + return this.contextIndex; } @Override @@ -76,7 +78,7 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator { if (environment instanceof ConfigurableEnvironment) { ConfigurableEnvironment env = (ConfigurableEnvironment) environment; - String appName = properties.getName(); + String appName = this.properties.getName(); if (appName == null) { appName = env.getProperty("spring.application.name"); @@ -89,13 +91,15 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator { List suffixes = new ArrayList<>(); if (this.properties.getFormat() != FILES) { suffixes.add("/"); - } else { + } + else { suffixes.add(".yml"); suffixes.add(".yaml"); suffixes.add(".properties"); } - String defaultContext = getContext(prefix, this.properties.getDefaultContext()); + String defaultContext = getContext(prefix, + this.properties.getDefaultContext()); for (String suffix : suffixes) { this.contexts.add(defaultContext + suffix); @@ -121,25 +125,32 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator { try { ConsulPropertySource propertySource = null; if (this.properties.getFormat() == FILES) { - Response response = this.consul.getKVValue(propertySourceContext, this.properties.getAclToken()); + Response response = this.consul.getKVValue( + propertySourceContext, this.properties.getAclToken()); addIndex(propertySourceContext, response.getConsulIndex()); if (response.getValue() != null) { - ConsulFilesPropertySource filesPropertySource = new ConsulFilesPropertySource(propertySourceContext, this.consul, this.properties); + ConsulFilesPropertySource filesPropertySource = new ConsulFilesPropertySource( + propertySourceContext, this.consul, this.properties); filesPropertySource.init(response.getValue()); propertySource = filesPropertySource; } - } else { - propertySource = create(propertySourceContext, contextIndex); + } + else { + propertySource = create(propertySourceContext, this.contextIndex); } if (propertySource != null) { composite.addPropertySource(propertySource); } - } catch (Exception e) { + } + catch (Exception e) { if (this.properties.isFailFast()) { - log.error("Fail fast is set and there was an error reading configuration from consul."); + log.error( + "Fail fast is set and there was an error reading configuration from consul."); ReflectionUtils.rethrowRuntimeException(e); - } else { - log.warn("Unable to load consul config from "+ propertySourceContext, e); + } + else { + log.warn("Unable to load consul config from " + + propertySourceContext, e); } } } @@ -152,26 +163,30 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator { private String getContext(String prefix, String context) { if (StringUtils.isEmpty(prefix)) { return context; - } else { + } + else { return prefix + "/" + context; } } private void addIndex(String propertySourceContext, Long consulIndex) { - contextIndex.put(propertySourceContext, consulIndex); + this.contextIndex.put(propertySourceContext, consulIndex); } private ConsulPropertySource create(String context, Map contextIndex) { - ConsulPropertySource propertySource = new ConsulPropertySource(context, this.consul, this.properties); + ConsulPropertySource propertySource = new ConsulPropertySource(context, + this.consul, this.properties); propertySource.init(); addIndex(context, propertySource.getInitialIndex()); return propertySource; } private void addProfiles(List contexts, String baseContext, - List profiles, String suffix) { + List profiles, String suffix) { for (String profile : profiles) { - contexts.add(baseContext + this.properties.getProfileSeparator() + profile + suffix); + contexts.add(baseContext + this.properties.getProfileSeparator() + profile + + suffix); } } + } diff --git a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/PropertySourcesLocatedEvent.java b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/PropertySourcesLocatedEvent.java index 6eed107d..e02c3247 100644 --- a/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/PropertySourcesLocatedEvent.java +++ b/spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/PropertySourcesLocatedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package org.springframework.cloud.consul.config; -import org.springframework.context.ApplicationEvent; - import java.util.LinkedHashMap; +import org.springframework.context.ApplicationEvent; + /** * @author Spencer Gibb */ @@ -29,15 +29,17 @@ public class PropertySourcesLocatedEvent extends ApplicationEvent { /** * Create a new ApplicationEvent. - * * @param source the object on which the event initially occurred (never {@code null}) + * @param contextsToIndexes contexts to indexes */ - public PropertySourcesLocatedEvent(Object source, LinkedHashMap contextsToIndexes) { + public PropertySourcesLocatedEvent(Object source, + LinkedHashMap contextsToIndexes) { super(source); this.contextsToIndexes = contextsToIndexes; } public LinkedHashMap getContextsToIndexes() { - return contextsToIndexes; + return this.contextsToIndexes; } + } diff --git a/spring-cloud-consul-config/src/main/resources/META-INF/spring.factories b/spring-cloud-consul-config/src/main/resources/META-INF/spring.factories index d1699b34..1e7e41f9 100644 --- a/spring-cloud-consul-config/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-consul-config/src/main/resources/META-INF/spring.factories @@ -1,7 +1,6 @@ # Auto Configuration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.consul.config.ConsulConfigAutoConfiguration - # Bootstrap Configuration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ org.springframework.cloud.consul.config.ConsulConfigBootstrapConfiguration diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConfigWatchTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConfigWatchTests.java index 37ed4511..24c32cd0 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConfigWatchTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConfigWatchTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,22 @@ package org.springframework.cloud.consul.config; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; + import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.QueryParams; import com.ecwid.consul.v1.Response; import com.ecwid.consul.v1.kv.model.GetValue; import org.junit.Before; import org.junit.Test; + import org.springframework.cloud.endpoint.event.RefreshEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.util.StringUtils; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; - import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; @@ -52,14 +53,15 @@ public class ConfigWatchTests { @Before public void setUp() throws Exception { - configProperties = new ConsulConfigProperties(); + this.configProperties = new ConsulConfigProperties(); } @Test public void watchPublishesEventWithAcl() { ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class); - setupWatch(eventPublisher, new GetValue(), "/app/", "2ee647bd-bd69-4118-9f34-b9a6e9e60746"); + setupWatch(eventPublisher, new GetValue(), "/app/", + "2ee647bd-bd69-4118-9f34-b9a6e9e60746"); verify(eventPublisher, atLeastOnce()).publishEvent(any(RefreshEvent.class)); } @@ -86,17 +88,19 @@ public class ConfigWatchTests { public void watchForFileFormatPublishesEvent() { ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class); - configProperties.setFormat(FILES); - setupWatch(eventPublisher, new GetValue(), "/config/app.yml" ); + this.configProperties.setFormat(FILES); + setupWatch(eventPublisher, new GetValue(), "/config/app.yml"); verify(eventPublisher, times(1)).publishEvent(any(RefreshEvent.class)); } - private void setupWatch(ApplicationEventPublisher eventPublisher, GetValue getValue, String context) { + private void setupWatch(ApplicationEventPublisher eventPublisher, GetValue getValue, + String context) { setupWatch(eventPublisher, getValue, context, null); } - private void setupWatch(ApplicationEventPublisher eventPublisher, GetValue getValue, String context, String aclToken) { + private void setupWatch(ApplicationEventPublisher eventPublisher, GetValue getValue, + String context, String aclToken) { ConsulClient consul = mock(ConsulClient.class); List getValues = null; @@ -105,15 +109,17 @@ public class ConfigWatchTests { } Response> response = new Response<>(getValues, 1L, false, 1L); - when(consul.getKVValues(eq(context), nullable(String.class), any(QueryParams.class))).thenReturn(response); + when(consul.getKVValues(eq(context), nullable(String.class), + any(QueryParams.class))).thenReturn(response); if (StringUtils.hasText(aclToken)) { - configProperties.setAclToken(aclToken); + this.configProperties.setAclToken(aclToken); } LinkedHashMap initialIndexes = new LinkedHashMap<>(); initialIndexes.put(context, 0L); - ConfigWatch watch = new ConfigWatch(configProperties, consul, initialIndexes); + ConfigWatch watch = new ConfigWatch(this.configProperties, consul, + initialIndexes); watch.setApplicationEventPublisher(eventPublisher); watch.start(); @@ -123,7 +129,7 @@ public class ConfigWatchTests { @Test public void firstCallDoesNotPublishEvent() { ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class); - configProperties.setFormat(FILES); + this.configProperties.setFormat(FILES); GetValue getValue = new GetValue(); String context = "/config/app.yml"; @@ -131,9 +137,11 @@ public class ConfigWatchTests { List getValues = Collections.singletonList(getValue); Response> response = new Response<>(getValues, 1L, false, 1L); - when(consul.getKVValues(eq(context), anyString(), any(QueryParams.class))).thenReturn(response); + when(consul.getKVValues(eq(context), anyString(), any(QueryParams.class))) + .thenReturn(response); - ConfigWatch watch = new ConfigWatch(configProperties, consul, new LinkedHashMap()); + ConfigWatch watch = new ConfigWatch(this.configProperties, consul, + new LinkedHashMap()); watch.setApplicationEventPublisher(eventPublisher); watch.watchConfigKeyValues(); diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfigurationTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfigurationTests.java index 783ebdaf..2fdc9029 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfigurationTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfigurationTests.java @@ -1,50 +1,76 @@ +/* + * Copyright 2013-2019 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.consul.config; -import org.junit.Assert; import org.junit.Test; + import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Edvin Eriksson */ public class ConsulConfigBootstrapConfigurationTests { + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); /** - * Tests that the auto-config bean backs off if a user provided their own + * Tests that the auto-config bean backs off if a user provided their own. */ @Test public void testConfigPropsBeanBacksOff() { - contextRunner - .withUserConfiguration(TestConfig.class) - .withUserConfiguration(ConsulConfigBootstrapConfiguration.class) - .run(context -> { - ConsulConfigProperties config = context.getBean(ConsulConfigProperties.class); - Assert.assertEquals("Prefix did not match", "platform-config", config.getPrefix()); - Assert.assertEquals("Default context did not match", "defaults", config.getDefaultContext()); - }); + this.contextRunner.withUserConfiguration(TestConfig.class) + .withUserConfiguration(ConsulConfigBootstrapConfiguration.class) + .run(context -> { + ConsulConfigProperties config = context + .getBean(ConsulConfigProperties.class); + assertThat(config.getPrefix()).as("Prefix did not match") + .isEqualTo("platform-config"); + assertThat(config.getDefaultContext()) + .as("Default context did not match").isEqualTo("defaults"); + }); } /** - * Tests that the auto-config bean kicks in if the user did not provide any custom bean. + * Tests that the auto-config bean kicks in if the user did not provide any custom + * bean. */ @Test public void testConfigPropsBeanKicksIn() { - contextRunner - .withUserConfiguration(ConsulConfigBootstrapConfiguration.class) - .run(context -> { - ConsulConfigProperties config = context.getBean(ConsulConfigProperties.class); - Assert.assertEquals("Prefix did not match", "config", config.getPrefix()); - Assert.assertEquals("Default context did not match", "application", config.getDefaultContext()); - }); + this.contextRunner.withUserConfiguration(ConsulConfigBootstrapConfiguration.class) + .run(context -> { + ConsulConfigProperties config = context + .getBean(ConsulConfigProperties.class); + assertThat(config.getPrefix()).as("Prefix did not match") + .isEqualTo("config"); + assertThat(config.getDefaultContext()) + .as("Default context did not match").isEqualTo("application"); + }); } + } /** - * Test config that simulates a "user provided bean" + * Test config that simulates a "user provided bean". */ class TestConfig { + @Bean public ConsulConfigProperties consulConfigProperties() { ConsulConfigProperties config = new ConsulConfigProperties(); @@ -52,4 +78,5 @@ class TestConfig { config.setDefaultContext("defaults"); return config; } -} \ No newline at end of file + +} diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertyPrefixTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertyPrefixTests.java index 460bed9e..e7cfb0ee 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertyPrefixTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertyPrefixTests.java @@ -1,15 +1,29 @@ +/* + * Copyright 2013-2019 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.consul.config; import com.ecwid.consul.v1.ConsulClient; import org.junit.After; import org.junit.Before; import org.junit.Test; + import org.springframework.cloud.consul.ConsulProperties; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class ConsulPropertyPrefixTests { @@ -18,37 +32,44 @@ public class ConsulPropertyPrefixTests { @Before public void setup() { ConsulProperties properties = new ConsulProperties(); - client = new ConsulClient(properties.getHost(), properties.getPort()); + this.client = new ConsulClient(properties.getHost(), properties.getPort()); } @After public void teardown() { - client.deleteKVValues(""); + this.client.deleteKVValues(""); } @Test public void testEmptyPrefix() { // because prefix is empty, a leading forward slash is omitted String kvContext = "appname"; - client.setKVValue(kvContext + "/fooprop", "fookvval"); - client.setKVValue(kvContext + "/bar/prop", "8080"); + this.client.setKVValue(kvContext + "/fooprop", "fookvval"); + this.client.setKVValue(kvContext + "/bar/prop", "8080"); - ConsulPropertySource source = getConsulPropertySource(new ConsulConfigProperties(), kvContext); + ConsulPropertySource source = getConsulPropertySource( + new ConsulConfigProperties(), kvContext); assertProperties(source, "fookvval", "8080"); } - private void assertProperties(ConsulPropertySource source, Object fooval, Object barval) { - assertThat("fooprop was wrong", source.getProperty("fooprop"), is(equalTo(fooval))); - assertThat("bar.prop was wrong", source.getProperty("bar.prop"), is(equalTo(barval))); + private void assertProperties(ConsulPropertySource source, Object fooval, + Object barval) { + assertThat(source.getProperty("fooprop")).as("fooprop was wrong") + .isEqualTo(fooval); + assertThat(source.getProperty("bar.prop")).as("bar.prop was wrong") + .isEqualTo(barval); } @SuppressWarnings("Duplicates") - private ConsulPropertySource getConsulPropertySource(ConsulConfigProperties configProperties, String context) { - ConsulPropertySource source = new ConsulPropertySource(context, client, configProperties); + private ConsulPropertySource getConsulPropertySource( + ConsulConfigProperties configProperties, String context) { + ConsulPropertySource source = new ConsulPropertySource(context, this.client, + configProperties); source.init(); String[] names = source.getPropertyNames(); - assertThat("names was null", names, is(notNullValue())); - assertThat("names was wrong size", names.length, is(equalTo(2))); + assertThat(names).as("names was null").isNotNull(); + assertThat(names.length).as("names was wrong size").isEqualTo(2); return source; } + } diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorAppNameCustomizedTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorAppNameCustomizedTests.java index 9f1d7e28..870d7df5 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorAppNameCustomizedTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorAppNameCustomizedTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 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. @@ -18,9 +18,11 @@ package org.springframework.cloud.consul.config; import java.util.UUID; +import com.ecwid.consul.v1.ConsulClient; import org.junit.After; import org.junit.Before; import org.junit.Test; + import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -30,57 +32,58 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.test.annotation.DirtiesContext; -import com.ecwid.consul.v1.ConsulClient; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Spencer Gibb */ @DirtiesContext public class ConsulPropertySourceLocatorAppNameCustomizedTests { + private static final String PREFIX = "_propertySourceLocatorAppNameCustomizedTests_config__"; + private static final String ROOT = PREFIX + UUID.randomUUID(); + private static final String VALUE1 = "testPropVal"; + private static final String TEST_PROP = "testProp"; + private static final String CONFIG_NAME = "myconfigfolder"; - private static final String KEY1 = ROOT + "/"+ CONFIG_NAME +"/"+ TEST_PROP; + + private static final String KEY1 = ROOT + "/" + CONFIG_NAME + "/" + TEST_PROP; + private static final String VALUE2 = "testPropVal2"; + private static final String TEST_PROP2 = "testProp2"; - private static final String KEY2 = ROOT + "/"+ CONFIG_NAME +"/"+ TEST_PROP2; + + private static final String KEY2 = ROOT + "/" + CONFIG_NAME + "/" + TEST_PROP2; private ConfigurableApplicationContext context; - @Configuration - @EnableAutoConfiguration - static class Config { - - } - private ConfigurableEnvironment environment; + private ConsulClient client; + private ConsulProperties properties; @Before public void setup() { this.properties = new ConsulProperties(); - this.client = new ConsulClient(properties.getHost(), properties.getPort()); + this.client = new ConsulClient(this.properties.getHost(), + this.properties.getPort()); this.client.deleteKVValues(PREFIX); this.client.setKVValue(KEY1, VALUE1); this.client.setKVValue(KEY2, VALUE2); - this.context = new SpringApplicationBuilder(Config.class) .web(WebApplicationType.NONE) .run("--spring.application.name=testConsulPropertySourceLocatorAppNameCustomized", - "--spring.cloud.consul.config.name="+CONFIG_NAME, - "--spring.cloud.consul.config.prefix="+ROOT); + "--spring.cloud.consul.config.name=" + CONFIG_NAME, + "--spring.cloud.consul.config.prefix=" + ROOT); - this.client = context.getBean(ConsulClient.class); - this.properties = context.getBean(ConsulProperties.class); - this.environment = context.getEnvironment(); + this.client = this.context.getBean(ConsulClient.class); + this.properties = this.context.getBean(ConsulProperties.class); + this.environment = this.context.getEnvironment(); } @After @@ -92,9 +95,16 @@ public class ConsulPropertySourceLocatorAppNameCustomizedTests { @Test public void propertyLoaded() throws Exception { String testProp = this.environment.getProperty(TEST_PROP); - assertThat("testProp was wrong", testProp, is(equalTo(VALUE1))); + assertThat(testProp).as("testProp was wrong").isEqualTo(VALUE1); String testProp2 = this.environment.getProperty(TEST_PROP2); - assertThat("testProp2 was wrong", testProp2, is(equalTo(VALUE2))); + assertThat(testProp2).as("testProp2 was wrong").isEqualTo(VALUE2); } + + @Configuration + @EnableAutoConfiguration + static class Config { + + } + } diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFailFastTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFailFastTests.java index 8080ba64..630450e0 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFailFastTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFailFastTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,6 +18,7 @@ package org.springframework.cloud.consul.config; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Configuration; @@ -29,22 +30,21 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulPropertySourceLocatorFailFastTests.Config.class, - properties = {"spring.application.name=testConsulPropertySourceLocatorFailFast", +@SpringBootTest(classes = ConsulPropertySourceLocatorFailFastTests.Config.class, properties = { + "spring.application.name=testConsulPropertySourceLocatorFailFast", "spring.cloud.consul.host=53210a7c-4809-42cb-8b30-057d2db85fcc", - "spring.cloud.consul.port=65530", - "spring.cloud.consul.retry.maxAttempts=0", - "spring.cloud.consul.config.failFast=false"}, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.port=65530", "spring.cloud.consul.retry.maxAttempts=0", + "spring.cloud.consul.config.failFast=false" }, webEnvironment = RANDOM_PORT) public class ConsulPropertySourceLocatorFailFastTests { - @Configuration - @EnableAutoConfiguration - static class Config { - } - @Test public void testFailFastFalse() { } + @Configuration + @EnableAutoConfiguration + static class Config { + + } + } diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFilesTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFilesTests.java index 536d0315..e433d183 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFilesTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFilesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,11 @@ import java.util.Collection; import java.util.Iterator; import java.util.UUID; +import com.ecwid.consul.v1.ConsulClient; import org.junit.After; import org.junit.Before; import org.junit.Test; + import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -35,62 +37,59 @@ import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import org.springframework.test.annotation.DirtiesContext; -import com.ecwid.consul.v1.ConsulClient; - -import static org.hamcrest.Matchers.endsWith; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.typeCompatibleWith; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Spencer Gibb */ @DirtiesContext public class ConsulPropertySourceLocatorFilesTests { + public static final String PREFIX = "_propertySourceLocatorFilesTests_config__"; + public static final String ROOT = PREFIX + UUID.randomUUID(); + public static final String APP_NAME = "testFilesFormat"; + public static final String APPLICATION_YML = "/application.yml"; + public static final String APPLICATION_DEV_YML = "/application-dev.yaml"; - public static final String APP_NAME_PROPS = "/"+APP_NAME+".properties"; - public static final String APP_NAME_DEV_PROPS = "/"+APP_NAME+"-dev.properties"; + + public static final String APP_NAME_PROPS = "/" + APP_NAME + ".properties"; + + public static final String APP_NAME_DEV_PROPS = "/" + APP_NAME + "-dev.properties"; private ConfigurableApplicationContext context; - @Configuration - @EnableAutoConfiguration - static class Config { - - } - private ConfigurableEnvironment environment; + private ConsulClient client; + private ConsulProperties properties; @Before public void setup() { this.properties = new ConsulProperties(); - this.client = new ConsulClient(properties.getHost(), properties.getPort()); - this.client.setKVValue(ROOT+ APPLICATION_YML, "foo: bar\nmy.baz: ${foo}"); - this.client.setKVValue(ROOT+ APPLICATION_DEV_YML, "foo: bar-dev\nmy.baz: ${foo}"); - this.client.setKVValue(ROOT+"/master.ref", UUID.randomUUID().toString()); - this.client.setKVValue(ROOT+APP_NAME_PROPS, "foo: bar-app\nmy.baz: ${foo}"); - this.client.setKVValue(ROOT+APP_NAME_DEV_PROPS, "foo: bar-app-dev\nmy.baz: ${foo}"); + this.client = new ConsulClient(this.properties.getHost(), + this.properties.getPort()); + this.client.setKVValue(ROOT + APPLICATION_YML, "foo: bar\nmy.baz: ${foo}"); + this.client.setKVValue(ROOT + APPLICATION_DEV_YML, + "foo: bar-dev\nmy.baz: ${foo}"); + this.client.setKVValue(ROOT + "/master.ref", UUID.randomUUID().toString()); + this.client.setKVValue(ROOT + APP_NAME_PROPS, "foo: bar-app\nmy.baz: ${foo}"); + this.client.setKVValue(ROOT + APP_NAME_DEV_PROPS, + "foo: bar-app-dev\nmy.baz: ${foo}"); this.context = new SpringApplicationBuilder(Config.class) - .web(WebApplicationType.NONE) - .run("--spring.application.name="+ APP_NAME, - "--spring.cloud.consul.config.prefix="+ROOT, + .web(WebApplicationType.NONE).run("--spring.application.name=" + APP_NAME, + "--spring.cloud.consul.config.prefix=" + ROOT, "--spring.cloud.consul.config.format=FILES", "--spring.profiles.active=dev", "spring.cloud.consul.config.watch.delay=1"); - this.client = context.getBean(ConsulClient.class); - this.properties = context.getBean(ConsulProperties.class); - this.environment = context.getEnvironment(); + this.client = this.context.getBean(ConsulClient.class); + this.properties = this.context.getBean(ConsulProperties.class); + this.environment = this.context.getEnvironment(); } @After @@ -104,32 +103,48 @@ public class ConsulPropertySourceLocatorFilesTests { @Test public void propertySourcesFound() throws Exception { String foo = this.environment.getProperty("foo"); - assertThat("foo was wrong", foo, is(equalTo("bar-app-dev"))); + assertThat(foo).as("foo was wrong").isEqualTo("bar-app-dev"); String myBaz = this.environment.getProperty("my.baz"); - assertThat("my.baz was wrong", myBaz, is(equalTo("bar-app-dev"))); + assertThat(myBaz).as("my.baz was wrong").isEqualTo("bar-app-dev"); MutablePropertySources propertySources = this.environment.getPropertySources(); - PropertySource bootstrapProperties = propertySources.get("bootstrapProperties"); - assertThat("bootstrapProperties was null", bootstrapProperties, is(notNullValue())); - assertThat("bootstrapProperties was wrong type", bootstrapProperties.getClass(), is(typeCompatibleWith(CompositePropertySource.class))); + PropertySource bootstrapProperties = propertySources + .get("bootstrapProperties"); + assertThat(bootstrapProperties).as("bootstrapProperties was null").isNotNull(); + assertThat(bootstrapProperties.getClass()) + .as("bootstrapProperties was wrong type") + .isInstanceOf(CompositePropertySource.class); - Collection> consulSources = ((CompositePropertySource) bootstrapProperties).getPropertySources(); - assertThat("consulSources was wrong size", consulSources, hasSize(1)); + Collection> consulSources = ((CompositePropertySource) bootstrapProperties) + .getPropertySources(); + assertThat(consulSources).as("consulSources was wrong size").hasSize(1); PropertySource consulSource = consulSources.iterator().next(); - assertThat("consulSource was wrong type", consulSource.getClass(), is(typeCompatibleWith(CompositePropertySource.class))); - Collection> fileSources = ((CompositePropertySource) consulSource).getPropertySources(); - assertThat("fileSources was wrong size", fileSources, hasSize(4)); + assertThat(consulSource.getClass()).as("consulSource was wrong type") + .isInstanceOf(CompositePropertySource.class); + Collection> fileSources = ((CompositePropertySource) consulSource) + .getPropertySources(); + assertThat(fileSources).as("fileSources was wrong size").hasSize(4); - assertFileSourceNames(fileSources, APP_NAME_DEV_PROPS, APP_NAME_PROPS, APPLICATION_DEV_YML, APPLICATION_YML); + assertFileSourceNames(fileSources, APP_NAME_DEV_PROPS, APP_NAME_PROPS, + APPLICATION_DEV_YML, APPLICATION_YML); } - private void assertFileSourceNames(Collection> fileSources, String... names) { + private void assertFileSourceNames(Collection> fileSources, + String... names) { Iterator> iterator = fileSources.iterator(); for (String name : names) { PropertySource fileSource = iterator.next(); - assertThat("fileSources was wrong name", fileSource.getName(), endsWith(name)); + assertThat(fileSource.getName()).as("fileSources was wrong name") + .endsWith(name); } } + + @Configuration + @EnableAutoConfiguration + static class Config { + + } + } diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorTests.java index 39706f82..27fcb906 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,12 @@ import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import com.ecwid.consul.v1.ConsulClient; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; + import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -36,35 +38,117 @@ import org.springframework.context.event.EventListener; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.test.annotation.DirtiesContext; -import com.ecwid.consul.v1.ConsulClient; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Spencer Gibb */ @DirtiesContext public class ConsulPropertySourceLocatorTests { + private static final String APP_NAME = "testConsulPropertySourceLocator"; + private static final String PREFIX = "_propertySourceLocatorTests_config__"; + private static final String ROOT = PREFIX + UUID.randomUUID(); + private static final String VALUE1 = "testPropVal"; + private static final String TEST_PROP = "testProp"; + private static final String TEST_PROP_CANONICAL = "test-prop"; - private static final String KEY1 = ROOT + "/application/"+ TEST_PROP; + + private static final String KEY1 = ROOT + "/application/" + TEST_PROP; + private static final String VALUE2 = "testPropVal2"; + private static final String TEST_PROP2 = "testProp2"; + private static final String TEST_PROP2_CANONICAL = "test-prop2"; - private static final String KEY2 = ROOT + "/application/"+ TEST_PROP2; + + private static final String KEY2 = ROOT + "/application/" + TEST_PROP2; + private static final String TEST_PROP3 = "testProp3"; + private static final String TEST_PROP3_CANONICAL = "test-prop3"; - private static final String KEY3 = ROOT + "/"+APP_NAME+"/"+ TEST_PROP3; + + private static final String KEY3 = ROOT + "/" + APP_NAME + "/" + TEST_PROP3; private ConfigurableApplicationContext context; + private ConfigurableEnvironment environment; + + private ConsulClient client; + + private ConsulProperties properties; + + @Before + public void setup() { + this.properties = new ConsulProperties(); + this.client = new ConsulClient(this.properties.getHost(), + this.properties.getPort()); + this.client.deleteKVValues(PREFIX); + this.client.setKVValue(KEY1, VALUE1); + this.client.setKVValue(KEY2, VALUE2); + + this.context = new SpringApplicationBuilder(Config.class) + .web(WebApplicationType.NONE).run("--SPRING_APPLICATION_NAME=" + APP_NAME, + "--spring.cloud.consul.config.prefix=" + ROOT, + "spring.cloud.consul.config.watch.delay=10"); + + this.client = this.context.getBean(ConsulClient.class); + this.properties = this.context.getBean(ConsulProperties.class); + this.environment = this.context.getEnvironment(); + } + + @After + public void teardown() { + this.client.deleteKVValues(PREFIX); + this.context.close(); + } + + @Test + public void propertyLoaded() throws Exception { + String testProp = this.environment.getProperty(TEST_PROP2_CANONICAL); + assertThat(testProp).as("testProp was wrong").isEqualTo(VALUE2); + } + + @Test + @Ignore // FIXME broken tests with boot 2.0.0 + public void propertyLoadedAndUpdated() throws Exception { + String testProp = this.environment.getProperty(TEST_PROP_CANONICAL); + assertThat(testProp).as("testProp was wrong").isEqualTo(VALUE1); + + this.client.setKVValue(KEY1, "testPropValUpdate"); + + CountDownLatch latch = this.context.getBean("countDownLatch1", + CountDownLatch.class); + boolean receivedEvent = latch.await(15, TimeUnit.SECONDS); + assertThat(receivedEvent).as("listener didn't receive event").isTrue(); + + testProp = this.environment.getProperty(TEST_PROP_CANONICAL); + assertThat(testProp).as("testProp was wrong after update") + .isEqualTo("testPropValUpdate"); + } + + @Test + @Ignore // FIXME broken tests with boot 2.0.0 + public void contextDoesNotExistThenExists() throws Exception { + String testProp = this.environment.getProperty(TEST_PROP3_CANONICAL); + assertThat(testProp).as("testProp was wrong").isNull(); + + this.client.setKVValue(KEY3, "testPropValInsert"); + + CountDownLatch latch = this.context.getBean("countDownLatch2", + CountDownLatch.class); + boolean receivedEvent = latch.await(15, TimeUnit.SECONDS); + assertThat(receivedEvent).as("listener didn't receive event").isTrue(); + + testProp = this.environment.getProperty(TEST_PROP3_CANONICAL); + assertThat(testProp).as(TEST_PROP3 + " was wrong after update") + .isEqualTo("testPropValInsert"); + } + @Configuration @EnableAutoConfiguration static class Config { @@ -83,77 +167,12 @@ public class ConsulPropertySourceLocatorTests { public void handle(EnvironmentChangeEvent event) { if (event.getKeys().contains(TEST_PROP)) { countDownLatch1().countDown(); - } else if (event.getKeys().contains(TEST_PROP3)) { + } + else if (event.getKeys().contains(TEST_PROP3)) { countDownLatch2().countDown(); } } + } - private ConfigurableEnvironment environment; - private ConsulClient client; - private ConsulProperties properties; - - @Before - public void setup() { - this.properties = new ConsulProperties(); - this.client = new ConsulClient(properties.getHost(), properties.getPort()); - this.client.deleteKVValues(PREFIX); - this.client.setKVValue(KEY1, VALUE1); - this.client.setKVValue(KEY2, VALUE2); - - - this.context = new SpringApplicationBuilder(Config.class) - .web(WebApplicationType.NONE) - .run("--SPRING_APPLICATION_NAME="+ APP_NAME, - "--spring.cloud.consul.config.prefix="+ROOT, - "spring.cloud.consul.config.watch.delay=10"); - - this.client = context.getBean(ConsulClient.class); - this.properties = context.getBean(ConsulProperties.class); - this.environment = context.getEnvironment(); - } - - @After - public void teardown() { - this.client.deleteKVValues(PREFIX); - this.context.close(); - } - - @Test - public void propertyLoaded() throws Exception { - String testProp = this.environment.getProperty(TEST_PROP2_CANONICAL); - assertThat("testProp was wrong", testProp, is(equalTo(VALUE2))); - } - - @Test - @Ignore // FIXME broken tests with boot 2.0.0 - public void propertyLoadedAndUpdated() throws Exception { - String testProp = this.environment.getProperty(TEST_PROP_CANONICAL); - assertThat("testProp was wrong", testProp, is(equalTo(VALUE1))); - - this.client.setKVValue(KEY1, "testPropValUpdate"); - - CountDownLatch latch = this.context.getBean("countDownLatch1", CountDownLatch.class); - boolean receivedEvent = latch.await(15, TimeUnit.SECONDS); - assertThat("listener didn't receive event", receivedEvent, is(true)); - - testProp = this.environment.getProperty(TEST_PROP_CANONICAL); - assertThat("testProp was wrong after update", testProp, is(equalTo("testPropValUpdate"))); - } - - @Test - @Ignore // FIXME broken tests with boot 2.0.0 - public void contextDoesNotExistThenExists() throws Exception { - String testProp = this.environment.getProperty(TEST_PROP3_CANONICAL); - assertThat("testProp was wrong", testProp, is(nullValue())); - - this.client.setKVValue(KEY3, "testPropValInsert"); - - CountDownLatch latch = this.context.getBean("countDownLatch2", CountDownLatch.class); - boolean receivedEvent = latch.await(15, TimeUnit.SECONDS); - assertThat("listener didn't receive event", receivedEvent, is(true)); - - testProp = this.environment.getProperty(TEST_PROP3_CANONICAL); - assertThat(TEST_PROP3 + " was wrong after update", testProp, is(equalTo("testPropValInsert"))); - } } diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceTests.java index af23bfc7..cda33307 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,67 +16,78 @@ package org.springframework.cloud.consul.config; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; - import java.util.Random; import com.ecwid.consul.v1.ConsulClient; - import org.junit.After; import org.junit.Before; import org.junit.Test; + import org.springframework.cloud.consul.ConsulProperties; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Spencer Gibb */ public class ConsulPropertySourceTests { private ConsulClient client; + private ConsulProperties properties; + private String prefix; + private String kvContext; + private String propertiesContext; @Before public void setup() { - properties = new ConsulProperties(); - prefix = "consulPropertySourceTests" + new Random().nextInt(Integer.MAX_VALUE); - client = new ConsulClient(properties.getHost(), properties.getPort()); + this.properties = new ConsulProperties(); + this.prefix = "consulPropertySourceTests" + + new Random().nextInt(Integer.MAX_VALUE); + this.client = new ConsulClient(this.properties.getHost(), + this.properties.getPort()); } @After public void teardown() { - client.deleteKVValues(prefix); + this.client.deleteKVValues(this.prefix); } @Test public void testKv() { // key value properties - kvContext = prefix + "/kv"; - client.setKVValue(kvContext + "/fooprop", "fookvval"); - client.setKVValue(prefix+"/kv"+"/bar/prop", "8080"); + this.kvContext = this.prefix + "/kv"; + this.client.setKVValue(this.kvContext + "/fooprop", "fookvval"); + this.client.setKVValue(this.prefix + "/kv" + "/bar/prop", "8080"); - ConsulPropertySource source = getConsulPropertySource(new ConsulConfigProperties(), kvContext); + ConsulPropertySource source = getConsulPropertySource( + new ConsulConfigProperties(), this.kvContext); assertProperties(source, "fookvval", "8080"); } - private void assertProperties(ConsulPropertySource source, Object fooval, Object barval) { - assertThat("fooprop was wrong", source.getProperty("fooprop"), is(equalTo(fooval))); - assertThat("bar.prop was wrong", source.getProperty("bar.prop"), is(equalTo(barval))); + private void assertProperties(ConsulPropertySource source, Object fooval, + Object barval) { + assertThat(source.getProperty("fooprop")).as("fooprop was wrong") + .isEqualTo(fooval); + assertThat(source.getProperty("bar.prop")).as("bar.prop was wrong") + .isEqualTo(barval); } @Test public void testProperties() { // properties file property - propertiesContext = prefix + "/properties"; - client.setKVValue(propertiesContext+"/data", "fooprop=foopropval\nbar.prop=8080"); + this.propertiesContext = this.prefix + "/properties"; + this.client.setKVValue(this.propertiesContext + "/data", + "fooprop=foopropval\nbar.prop=8080"); ConsulConfigProperties configProperties = new ConsulConfigProperties(); configProperties.setFormat(ConsulConfigProperties.Format.PROPERTIES); - ConsulPropertySource source = getConsulPropertySource(configProperties, propertiesContext); + ConsulPropertySource source = getConsulPropertySource(configProperties, + this.propertiesContext); assertProperties(source, "foopropval", "8080"); } @@ -84,12 +95,14 @@ public class ConsulPropertySourceTests { @Test public void testYaml() { // yaml file property - String yamlContext = prefix + "/yaml"; - client.setKVValue(yamlContext+"/data", "fooprop: fooymlval\nbar:\n prop: 8080"); + String yamlContext = this.prefix + "/yaml"; + this.client.setKVValue(yamlContext + "/data", + "fooprop: fooymlval\nbar:\n prop: 8080"); ConsulConfigProperties configProperties = new ConsulConfigProperties(); configProperties.setFormat(ConsulConfigProperties.Format.YAML); - ConsulPropertySource source = getConsulPropertySource(configProperties, yamlContext); + ConsulPropertySource source = getConsulPropertySource(configProperties, + yamlContext); assertProperties(source, "fooymlval", 8080); } @@ -97,22 +110,26 @@ public class ConsulPropertySourceTests { @Test public void testEmptyYaml() { // yaml file property - String yamlContext = prefix + "/yaml"; - client.setKVValue(yamlContext+"/data", ""); + String yamlContext = this.prefix + "/yaml"; + this.client.setKVValue(yamlContext + "/data", ""); ConsulConfigProperties configProperties = new ConsulConfigProperties(); configProperties.setFormat(ConsulConfigProperties.Format.YAML); - ConsulPropertySource source = new ConsulPropertySource(yamlContext, client, configProperties); + ConsulPropertySource source = new ConsulPropertySource(yamlContext, this.client, + configProperties); // Should NOT throw a NPE source.init(); } - private ConsulPropertySource getConsulPropertySource(ConsulConfigProperties configProperties, String context) { - ConsulPropertySource source = new ConsulPropertySource(context, client, configProperties); + private ConsulPropertySource getConsulPropertySource( + ConsulConfigProperties configProperties, String context) { + ConsulPropertySource source = new ConsulPropertySource(context, this.client, + configProperties); source.init(); String[] names = source.getPropertyNames(); - assertThat("names was null", names, is(notNullValue())); - assertThat("names was wrong size", names.length, is(equalTo(2))); + assertThat(names).as("names was null").isNotNull(); + assertThat(names.length).as("names was wrong size").isEqualTo(2); return source; } + } diff --git a/spring-cloud-consul-core/pom.xml b/spring-cloud-consul-core/pom.xml index 1e8b8870..3067dd8a 100644 --- a/spring-cloud-consul-core/pom.xml +++ b/spring-cloud-consul-core/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConditionalOnConsulEnabled.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConditionalOnConsulEnabled.java index 192973ff..f87219fe 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConditionalOnConsulEnabled.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConditionalOnConsulEnabled.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -22,26 +22,46 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.ecwid.consul.v1.ConsulClient; + import org.springframework.boot.autoconfigure.condition.AllNestedConditions; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Conditional; +/** + * When both property and consul classes are on the classpath. + * @author Spencer Gibb + */ @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD}) +@Target({ ElementType.TYPE, ElementType.METHOD }) @Conditional(ConditionalOnConsulEnabled.OnConsulEnabledCondition.class) public @interface ConditionalOnConsulEnabled { + /** + * Verifies multiple conditions to see if Consul should be enabled. + */ class OnConsulEnabledCondition extends AllNestedConditions { - public OnConsulEnabledCondition() { + OnConsulEnabledCondition() { super(ConfigurationPhase.REGISTER_BEAN); } + /** + * Consul property is enabled. + */ @ConditionalOnProperty(value = "spring.cloud.consul.enabled", matchIfMissing = true) - static class FoundProperty {} + static class FoundProperty { + } + + /** + * Consul client class found. + */ @ConditionalOnClass(ConsulClient.class) - static class FoundClass {} + static class FoundClass { + + } + } + } diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java index 67190553..752e7e42 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -19,6 +19,7 @@ package org.springframework.cloud.consul; import com.ecwid.consul.transport.TLSConfig; import com.ecwid.consul.v1.ConsulClient; import org.aspectj.lang.annotation.Aspect; + import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; @@ -33,8 +34,6 @@ import org.springframework.retry.annotation.EnableRetry; import org.springframework.retry.annotation.Retryable; import org.springframework.retry.interceptor.RetryInterceptorBuilder; import org.springframework.retry.interceptor.RetryOperationsInterceptor; - -import com.ecwid.consul.v1.ConsulClient; import org.springframework.util.StringUtils; /** @@ -61,13 +60,9 @@ public class ConsulAutoConfiguration { if (consulProperties.getTls() != null) { ConsulProperties.TLSConfig tls = consulProperties.getTls(); - TLSConfig tlsConfig = new TLSConfig( - tls.getKeyStoreInstanceType(), - tls.getCertificatePath(), - tls.getCertificatePassword(), - tls.getKeyStorePath(), - tls.getKeyStorePassword() - ); + TLSConfig tlsConfig = new TLSConfig(tls.getKeyStoreInstanceType(), + tls.getCertificatePath(), tls.getCertificatePassword(), + tls.getKeyStorePath(), tls.getKeyStorePassword()); return new ConsulClient(agentHost, agentPort, tlsConfig); } return new ConsulClient(agentHost, agentPort); @@ -90,6 +85,7 @@ public class ConsulAutoConfiguration { public ConsulHealthIndicator consulHealthIndicator(ConsulClient consulClient) { return new ConsulHealthIndicator(consulClient); } + } @ConditionalOnClass({ Retryable.class, Aspect.class, AopAutoConfiguration.class }) @@ -103,11 +99,12 @@ public class ConsulAutoConfiguration { @ConditionalOnMissingBean(name = "consulRetryInterceptor") public RetryOperationsInterceptor consulRetryInterceptor( RetryProperties properties) { - return RetryInterceptorBuilder - .stateless() + return RetryInterceptorBuilder.stateless() .backOffOptions(properties.getInitialInterval(), properties.getMultiplier(), properties.getMaxInterval()) .maxAttempts(properties.getMaxAttempts()).build(); } + } + } diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulEndpoint.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulEndpoint.java index a17711a9..fa3953ab 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulEndpoint.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -47,25 +47,30 @@ public class ConsulEndpoint { public ConsulData invoke() { ConsulData data = new ConsulData(); // data.setKeyValues(kvClient.getKeyValueRecurse()); - Response> agentServices = consul.getAgentServices(); + Response> agentServices = this.consul.getAgentServices(); data.setAgentServices(agentServices.getValue()); - Response>> catalogServices = consul + Response>> catalogServices = this.consul .getCatalogServices(QueryParams.DEFAULT); for (String serviceId : catalogServices.getValue().keySet()) { - Response> response = consul.getCatalogService(serviceId, - QueryParams.DEFAULT); + Response> response = this.consul + .getCatalogService(serviceId, QueryParams.DEFAULT); data.getCatalogServices().put(serviceId, response.getValue()); } - Response> catalogNodes = consul.getCatalogNodes(QueryParams.DEFAULT); + Response> catalogNodes = this.consul + .getCatalogNodes(QueryParams.DEFAULT); data.setCatalogNodes(catalogNodes.getValue()); return data; } + /** + * Represents Consul data related to catalog entries and agent servies. + */ public static class ConsulData { + Map> catalogServices = new LinkedHashMap<>(); Map agentServices; @@ -79,22 +84,23 @@ public class ConsulEndpoint { return this.catalogServices; } + public void setCatalogServices( + Map> catalogServices) { + this.catalogServices = catalogServices; + } + public Map getAgentServices() { return this.agentServices; } - public List getCatalogNodes() { - return this.catalogNodes; - } - - public void setCatalogServices(Map> catalogServices) { - this.catalogServices = catalogServices; - } - public void setAgentServices(Map agentServices) { this.agentServices = agentServices; } + public List getCatalogNodes() { + return this.catalogNodes; + } + public void setCatalogNodes(List catalogNodes) { this.catalogNodes = catalogNodes; } @@ -102,10 +108,11 @@ public class ConsulEndpoint { @Override public String toString() { return new ToStringCreator(this) - .append("catalogServices", catalogServices) - .append("agentServices", agentServices) - .append("catalogNodes", catalogNodes) - .toString(); + .append("catalogServices", this.catalogServices) + .append("agentServices", this.agentServices) + .append("catalogNodes", this.catalogNodes).toString(); } + } + } diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulHealthIndicator.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulHealthIndicator.java index 36fa103c..69f000d4 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulHealthIndicator.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulHealthIndicator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -19,13 +19,13 @@ package org.springframework.cloud.consul; import java.util.List; import java.util.Map; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; - import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.QueryParams; import com.ecwid.consul.v1.Response; +import org.springframework.boot.actuate.health.AbstractHealthIndicator; +import org.springframework.boot.actuate.health.Health; + /** * @author Spencer Gibb */ @@ -39,10 +39,11 @@ public class ConsulHealthIndicator extends AbstractHealthIndicator { @Override protected void doHealthCheck(Health.Builder builder) throws Exception { - final Response leaderStatus = consul.getStatusLeader(); - final Response>> services = consul + final Response leaderStatus = this.consul.getStatusLeader(); + final Response>> services = this.consul .getCatalogServices(QueryParams.DEFAULT); builder.up().withDetail("leader", leaderStatus.getValue()).withDetail("services", services.getValue()); } + } diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulProperties.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulProperties.java index f8dad7cc..24494537 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulProperties.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -30,26 +30,29 @@ import org.springframework.validation.annotation.Validated; @ConfigurationProperties("spring.cloud.consul") @Validated public class ConsulProperties { + /** Consul agent hostname. Defaults to 'localhost'. */ @NotNull private String host = "localhost"; - /** Consul agent scheme (HTTP/HTTPS). If there is no scheme in address - client will use HTTP. */ + /** + * Consul agent scheme (HTTP/HTTPS). If there is no scheme in address - client will + * use HTTP. + */ private String scheme; /** Consul agent port. Defaults to '8500'. */ @NotNull private int port = 8500; - /** Is spring cloud consul enabled */ + /** Is spring cloud consul enabled. */ private boolean enabled = true; - /** configuration for TLS */ + /** configuration for TLS. */ private TLSConfig tls; - public String getHost() { - return host; + return this.host; } public void setHost(String host) { @@ -57,7 +60,7 @@ public class ConsulProperties { } public int getPort() { - return port; + return this.port; } public void setPort(int port) { @@ -65,7 +68,7 @@ public class ConsulProperties { } public boolean isEnabled() { - return enabled; + return this.enabled; } public void setEnabled(boolean enabled) { @@ -73,7 +76,7 @@ public class ConsulProperties { } public String getScheme() { - return scheme; + return this.scheme; } public void setScheme(String scheme) { @@ -81,7 +84,7 @@ public class ConsulProperties { } public TLSConfig getTls() { - return tls; + return this.tls; } public void setTls(TLSConfig tls) { @@ -90,26 +93,26 @@ public class ConsulProperties { @Override public String toString() { - return "ConsulProperties{" + - "host='" + host + '\'' + - ", port=" + port + - ", scheme=" + scheme + - ", tls=" + tls + - ", enabled=" + enabled + - '}'; + return "ConsulProperties{" + "host='" + this.host + '\'' + ", port=" + this.port + + ", scheme=" + this.scheme + ", tls=" + this.tls + ", enabled=" + + this.enabled + '}'; } + /** + * TLS configuration. + */ public static class TLSConfig { + /** Type of key framework to use. */ private KeyStoreInstanceType keyStoreInstanceType; - /** Path to an external keystore */ + /** Path to an external keystore. */ private String keyStorePath; - /** Password to an external keystore */ + /** Password to an external keystore. */ private String keyStorePassword; - /**File path to the certificate. */ + /** File path to the certificate. */ private String certificatePath; /** Password to open the certificate. */ @@ -118,7 +121,9 @@ public class ConsulProperties { public TLSConfig() { } - public TLSConfig(KeyStoreInstanceType keyStoreInstanceType, String keyStorePath, String keyStorePassword, String certificatePath, String certificatePassword) { + public TLSConfig(KeyStoreInstanceType keyStoreInstanceType, String keyStorePath, + String keyStorePassword, String certificatePath, + String certificatePassword) { this.keyStoreInstanceType = keyStoreInstanceType; this.keyStorePath = keyStorePath; this.keyStorePassword = keyStorePassword; @@ -127,7 +132,7 @@ public class ConsulProperties { } public KeyStoreInstanceType getKeyStoreInstanceType() { - return keyStoreInstanceType; + return this.keyStoreInstanceType; } public void setKeyStoreInstanceType(KeyStoreInstanceType keyStoreInstanceType) { @@ -135,7 +140,7 @@ public class ConsulProperties { } public String getKeyStorePath() { - return keyStorePath; + return this.keyStorePath; } public void setKeyStorePath(String keyStorePath) { @@ -143,7 +148,7 @@ public class ConsulProperties { } public String getKeyStorePassword() { - return keyStorePassword; + return this.keyStorePassword; } public void setKeyStorePassword(String keyStorePassword) { @@ -151,7 +156,7 @@ public class ConsulProperties { } public String getCertificatePath() { - return certificatePath; + return this.certificatePath; } public void setCertificatePath(String certificatePath) { @@ -159,7 +164,7 @@ public class ConsulProperties { } public String getCertificatePassword() { - return certificatePassword; + return this.certificatePassword; } public void setCertificatePassword(String certificatePassword) { @@ -169,12 +174,13 @@ public class ConsulProperties { @Override public String toString() { return new ToStringCreator(this) - .append("keyStoreInstanceType", keyStoreInstanceType) - .append("keyStorePath", keyStorePath) - .append("keyStorePassword", keyStorePassword) - .append("certificatePath", certificatePath) - .append("certificatePassword", certificatePassword) - .toString(); + .append("keyStoreInstanceType", this.keyStoreInstanceType) + .append("keyStorePath", this.keyStorePath) + .append("keyStorePassword", this.keyStorePassword) + .append("certificatePath", this.certificatePath) + .append("certificatePassword", this.certificatePassword).toString(); } + } + } diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/RetryProperties.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/RetryProperties.java index d371b0f8..2910e80c 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/RetryProperties.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/RetryProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -44,41 +44,40 @@ public class RetryProperties { return this.initialInterval; } - public double getMultiplier() { - return this.multiplier; - } - - public long getMaxInterval() { - return this.maxInterval; - } - - public int getMaxAttempts() { - return this.maxAttempts; - } - public void setInitialInterval(long initialInterval) { this.initialInterval = initialInterval; } + public double getMultiplier() { + return this.multiplier; + } + public void setMultiplier(double multiplier) { this.multiplier = multiplier; } + public long getMaxInterval() { + return this.maxInterval; + } + public void setMaxInterval(long maxInterval) { this.maxInterval = maxInterval; } + public int getMaxAttempts() { + return this.maxAttempts; + } + public void setMaxAttempts(int maxAttempts) { this.maxAttempts = maxAttempts; } @Override public String toString() { - return new ToStringCreator(this) - .append("initialInterval", initialInterval) - .append("multiplier", multiplier) - .append("maxInterval", maxInterval) - .append("maxAttempts", maxAttempts) - .toString(); + return new ToStringCreator(this).append("initialInterval", this.initialInterval) + .append("multiplier", this.multiplier) + .append("maxInterval", this.maxInterval) + .append("maxAttempts", this.maxAttempts).toString(); } + } diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/SerfStatusEnum.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/SerfStatusEnum.java index d6e5982e..0aece88c 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/SerfStatusEnum.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/SerfStatusEnum.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -18,9 +18,30 @@ package org.springframework.cloud.consul.model; /** * Gossip pool (serf) statuses. Created by nicu on 10.03.2015. + * @author Nicu Marasoiu */ public enum SerfStatusEnum { - StatusAlive(1), StatusLeaving(2), StatusLeft(3), StatusFailed(4); + + /** + * Alive status. + */ + StatusAlive(1), + + /** + * Leaving status. + */ + StatusLeaving(2), + + /** + * Left status. + */ + StatusLeft(3), + + /** + * Failed status. + */ + StatusFailed(4); + private final int code; SerfStatusEnum(int code) { @@ -28,7 +49,7 @@ public enum SerfStatusEnum { } public int getCode() { - return code; + return this.code; } } diff --git a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulAutoConfigurationTests.java b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulAutoConfigurationTests.java index fe226ba1..25df08e0 100644 --- a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulAutoConfigurationTests.java +++ b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulAutoConfigurationTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2019 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.consul; import com.ecwid.consul.transport.DefaultHttpsTransport; @@ -18,11 +34,11 @@ import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) -@SpringBootTest(properties = {"spring.cloud.consul.tls.key-store-instance-type=JKS", +@SpringBootTest(properties = { "spring.cloud.consul.tls.key-store-instance-type=JKS", "spring.cloud.consul.tls.key-store-path=src/test/resources/server.jks", "spring.cloud.consul.tls.key-store-password=letmein", "spring.cloud.consul.tls.certificate-path=src/test/resources/trustStore.jks", - "spring.cloud.consul.tls.certificate-password=change_me", }) + "spring.cloud.consul.tls.certificate-password=change_me" }) public class ConsulAutoConfigurationTests { @Autowired @@ -30,13 +46,19 @@ public class ConsulAutoConfigurationTests { @Test public void tlsConfigured() { - CatalogConsulClient client = (CatalogConsulClient) ReflectionTestUtils.getField(consulClient, "catalogClient"); - ConsulRawClient rawClient = (ConsulRawClient) ReflectionTestUtils.getField(client, "rawClient"); - HttpTransport httpTransport = (HttpTransport) ReflectionTestUtils.getField(rawClient, "httpTransport"); + CatalogConsulClient client = (CatalogConsulClient) ReflectionTestUtils + .getField(this.consulClient, "catalogClient"); + ConsulRawClient rawClient = (ConsulRawClient) ReflectionTestUtils.getField(client, + "rawClient"); + HttpTransport httpTransport = (HttpTransport) ReflectionTestUtils + .getField(rawClient, "httpTransport"); assertThat(httpTransport).isInstanceOf(DefaultHttpsTransport.class); } @EnableAutoConfiguration @SpringBootConfiguration - protected static class TestConfig {} + protected static class TestConfig { + + } + } diff --git a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorDownTest.java b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorDownTest.java index 969251fe..8b640c2c 100644 --- a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorDownTest.java +++ b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorDownTest.java @@ -1,9 +1,24 @@ -package org.springframework.cloud.consul; +/* + * Copyright 2013-2019 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. + */ -import static org.junit.Assert.assertEquals; +package org.springframework.cloud.consul; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.actuate.health.HealthEndpoint; @@ -12,6 +27,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Lomesh Patel (lomeshpatel) */ @@ -24,12 +41,14 @@ public class ConsulHealthIndicatorDownTest { @Test public void doHealthCheck() { - assertEquals("health status was not DOWN", Status.DOWN, - healthEndpoint.health().getStatus()); + assertThat(this.healthEndpoint.health().getStatus()) + .as("health status was not DOWN").isEqualTo(Status.DOWN); } @EnableAutoConfiguration @SpringBootConfiguration protected static class TestConfig { + } -} \ No newline at end of file + +} diff --git a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorUpTest.java b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorUpTest.java index 503422cf..df898786 100644 --- a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorUpTest.java +++ b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorUpTest.java @@ -1,9 +1,24 @@ -package org.springframework.cloud.consul; +/* + * Copyright 2013-2019 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. + */ -import static org.junit.Assert.assertEquals; +package org.springframework.cloud.consul; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.actuate.health.HealthEndpoint; @@ -12,6 +27,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Lomesh Patel (lomeshpatel) */ @@ -24,12 +41,14 @@ public class ConsulHealthIndicatorUpTest { @Test public void doHealthCheck() { - assertEquals("health status was not UP", Status.UP, - healthEndpoint.health().getStatus()); + assertThat(this.healthEndpoint.health().getStatus()) + .as("health status was not UP").isEqualTo(Status.UP); } @EnableAutoConfiguration @SpringBootConfiguration protected static class TestConfig { + } -} \ No newline at end of file + +} diff --git a/spring-cloud-consul-dependencies/pom.xml b/spring-cloud-consul-dependencies/pom.xml index 061fb4cd..4a841829 100644 --- a/spring-cloud-consul-dependencies/pom.xml +++ b/spring-cloud-consul-dependencies/pom.xml @@ -1,12 +1,13 @@ - 4.0.0 spring-cloud-dependencies-parent org.springframework.cloud 2.1.3.BUILD-SNAPSHOT - + spring-cloud-consul-dependencies 2.1.1.BUILD-SNAPSHOT diff --git a/spring-cloud-consul-discovery/pom.xml b/spring-cloud-consul-discovery/pom.xml index 358f96aa..f4036bb0 100644 --- a/spring-cloud-consul-discovery/pom.xml +++ b/spring-cloud-consul-discovery/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulCatalogWatch.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulCatalogWatch.java index a8f04561..c8121aa8 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulCatalogWatch.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulCatalogWatch.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -40,20 +40,35 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; /** * @author Spencer Gibb */ -public class ConsulCatalogWatch implements ApplicationEventPublisherAware, SmartLifecycle { +public class ConsulCatalogWatch + implements ApplicationEventPublisherAware, SmartLifecycle { + private static final Log log = LogFactory.getLog(ConsulDiscoveryClient.class); private final ConsulDiscoveryProperties properties; + private final ConsulClient consul; + private final TaskScheduler taskScheduler; + private final AtomicReference catalogServicesIndex = new AtomicReference<>(); + private final AtomicBoolean running = new AtomicBoolean(false); + private ApplicationEventPublisher publisher; + private ScheduledFuture watchFuture; public ConsulCatalogWatch(ConsulDiscoveryProperties properties, ConsulClient consul) { this(properties, consul, getTaskScheduler()); - } + } + + public ConsulCatalogWatch(ConsulDiscoveryProperties properties, ConsulClient consul, + TaskScheduler taskScheduler) { + this.properties = properties; + this.consul = consul; + this.taskScheduler = taskScheduler; + } private static ThreadPoolTaskScheduler getTaskScheduler() { ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); @@ -61,12 +76,6 @@ public class ConsulCatalogWatch implements ApplicationEventPublisherAware, Smart return taskScheduler; } - public ConsulCatalogWatch(ConsulDiscoveryProperties properties, ConsulClient consul, TaskScheduler taskScheduler) { - this.properties = properties; - this.consul = consul; - this.taskScheduler = taskScheduler; - } - @Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; @@ -86,7 +95,8 @@ public class ConsulCatalogWatch implements ApplicationEventPublisherAware, Smart @Override public void start() { if (this.running.compareAndSet(false, true)) { - this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(this::catalogServicesWatch, + this.watchFuture = this.taskScheduler.scheduleWithFixedDelay( + this::catalogServicesWatch, this.properties.getCatalogServicesWatchDelay()); } } @@ -108,30 +118,32 @@ public class ConsulCatalogWatch implements ApplicationEventPublisherAware, Smart return 0; } - @Timed(value ="consul.watch-catalog-services") + @Timed("consul.watch-catalog-services") public void catalogServicesWatch() { try { long index = -1; - if (catalogServicesIndex.get() != null) { - index = catalogServicesIndex.get().longValue(); + if (this.catalogServicesIndex.get() != null) { + index = this.catalogServicesIndex.get().longValue(); } - Response>> response = consul - .getCatalogServices(new QueryParams(properties - .getCatalogServicesWatchTimeout(), index), properties.getAclToken()); + Response>> response = this.consul.getCatalogServices( + new QueryParams(this.properties.getCatalogServicesWatchTimeout(), + index), + this.properties.getAclToken()); Long consulIndex = response.getConsulIndex(); if (consulIndex != null) { - catalogServicesIndex.set(BigInteger.valueOf(consulIndex)); + this.catalogServicesIndex.set(BigInteger.valueOf(consulIndex)); } if (log.isTraceEnabled()) { - log.trace("Received services update from consul: "+response.getValue() - +", index: "+ consulIndex); + log.trace("Received services update from consul: " + response.getValue() + + ", index: " + consulIndex); } - publisher.publishEvent(new HeartbeatEvent(this, consulIndex)); + this.publisher.publishEvent(new HeartbeatEvent(this, consulIndex)); } catch (Exception e) { log.error("Error watching Consul CatalogServices", e); } } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClient.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClient.java index ec0d51cf..cbaea910 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClient.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-2019 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. @@ -44,16 +44,12 @@ public class ConsulDiscoveryClient implements DiscoveryClient { private static final Log log = LogFactory.getLog(ConsulDiscoveryClient.class); - @Deprecated - public interface LocalResolver { - String getInstanceId(); - Integer getPort(); - } - private final ConsulClient client; + private final ConsulDiscoveryProperties properties; - public ConsulDiscoveryClient(ConsulClient client, ConsulDiscoveryProperties properties) { + public ConsulDiscoveryClient(ConsulClient client, + ConsulDiscoveryProperties properties) { this.client = client; this.properties = properties; } @@ -80,15 +76,15 @@ public class ConsulDiscoveryClient implements DiscoveryClient { private void addInstancesToList(List instances, String serviceId, QueryParams queryParams) { - String aclToken = properties.getAclToken(); + String aclToken = this.properties.getAclToken(); Response> services; if (StringUtils.hasText(aclToken)) { - services = client.getHealthServices(serviceId, + services = this.client.getHealthServices(serviceId, this.properties.getDefaultQueryTag(), this.properties.isQueryPassing(), queryParams, aclToken); } else { - services = client.getHealthServices(serviceId, + services = this.client.getHealthServices(serviceId, this.properties.getDefaultQueryTag(), this.properties.isQueryPassing(), queryParams); } @@ -100,15 +96,15 @@ public class ConsulDiscoveryClient implements DiscoveryClient { if (metadata.containsKey("secure")) { secure = Boolean.parseBoolean(metadata.get("secure")); } - instances.add(new DefaultServiceInstance(service.getService().getId(), serviceId, host, service - .getService().getPort(), secure, metadata)); + instances.add(new DefaultServiceInstance(service.getService().getId(), + serviceId, host, service.getService().getPort(), secure, metadata)); } } public List getAllInstances() { List instances = new ArrayList<>(); - Response>> services = client + Response>> services = this.client .getCatalogServices(QueryParams.DEFAULT); for (String serviceId : services.getValue().keySet()) { addInstancesToList(instances, serviceId, QueryParams.DEFAULT); @@ -118,14 +114,16 @@ public class ConsulDiscoveryClient implements DiscoveryClient { @Override public List getServices() { - String aclToken = properties.getAclToken(); + String aclToken = this.properties.getAclToken(); if (StringUtils.hasText(aclToken)) { - return new ArrayList<>(client.getCatalogServices(QueryParams.DEFAULT, aclToken).getValue() - .keySet()); - } else { - return new ArrayList<>(client.getCatalogServices(QueryParams.DEFAULT).getValue() - .keySet()); + return new ArrayList<>( + this.client.getCatalogServices(QueryParams.DEFAULT, aclToken) + .getValue().keySet()); + } + else { + return new ArrayList<>(this.client.getCatalogServices(QueryParams.DEFAULT) + .getValue().keySet()); } } @@ -133,4 +131,17 @@ public class ConsulDiscoveryClient implements DiscoveryClient { public int getOrder() { return this.properties.getOrder(); } + + /** + * Depreacted local resolver. + */ + @Deprecated + public interface LocalResolver { + + String getInstanceId(); + + Integer getPort(); + + } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientConfiguration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientConfiguration.java index fcdb6e97..1a4ed37f 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientConfiguration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-2019 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. @@ -45,6 +45,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; CommonsClientAutoConfiguration.class }) public class ConsulDiscoveryClientConfiguration { + /** + * Name of the catalog watch task scheduler bean. + */ public static final String CATALOG_WATCH_TASK_SCHEDULER_NAME = "catalogWatchTaskScheduler"; @Autowired @@ -53,29 +56,30 @@ public class ConsulDiscoveryClientConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnProperty("spring.cloud.consul.discovery.heartbeat.enabled") - //TODO: move to service-registry for Edgware + // TODO: move to service-registry for Edgware public TtlScheduler ttlScheduler(HeartbeatProperties heartbeatProperties) { - return new TtlScheduler(heartbeatProperties, consulClient); + return new TtlScheduler(heartbeatProperties, this.consulClient); } @Bean @ConditionalOnMissingBean - //TODO: move to service-registry for Edgware + // TODO: move to service-registry for Edgware public HeartbeatProperties heartbeatProperties() { return new HeartbeatProperties(); } @Bean @ConditionalOnMissingBean - //TODO: Split appropriate values to service-registry for Edgware + // TODO: Split appropriate values to service-registry for Edgware public ConsulDiscoveryProperties consulDiscoveryProperties(InetUtils inetUtils) { return new ConsulDiscoveryProperties(inetUtils); } @Bean @ConditionalOnMissingBean - public ConsulDiscoveryClient consulDiscoveryClient(ConsulDiscoveryProperties discoveryProperties) { - return new ConsulDiscoveryClient(consulClient, discoveryProperties); + public ConsulDiscoveryClient consulDiscoveryClient( + ConsulDiscoveryProperties discoveryProperties) { + return new ConsulDiscoveryClient(this.consulClient, discoveryProperties); } @Bean @@ -84,7 +88,8 @@ public class ConsulDiscoveryClientConfiguration { public ConsulCatalogWatch consulCatalogWatch( ConsulDiscoveryProperties discoveryProperties, @Qualifier(CATALOG_WATCH_TASK_SCHEDULER_NAME) TaskScheduler taskScheduler) { - return new ConsulCatalogWatch(discoveryProperties, consulClient, taskScheduler); + return new ConsulCatalogWatch(discoveryProperties, this.consulClient, + taskScheduler); } @Bean(name = CATALOG_WATCH_TASK_SCHEDULER_NAME) @@ -92,4 +97,5 @@ public class ConsulDiscoveryClientConfiguration { public TaskScheduler catalogWatchTaskScheduler() { return new ThreadPoolTaskScheduler(); } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryProperties.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryProperties.java index 1ae49fb7..1ac893f4 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryProperties.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,17 @@ package org.springframework.cloud.consul.discovery; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.commons.util.InetUtils; import org.springframework.cloud.commons.util.InetUtils.HostInfo; import org.springframework.core.style.ToStringCreator; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - /** * Defines configuration for service discovery and registration. * @@ -45,22 +45,22 @@ public class ConsulDiscoveryProperties { @Value("${consul.token:${CONSUL_TOKEN:${spring.cloud.consul.token:${SPRING_CLOUD_CONSUL_TOKEN:}}}}") private String aclToken; - /** Tags to use when registering service */ + /** Tags to use when registering service. */ private List tags = new ArrayList<>(); /** Is service discovery enabled? */ private boolean enabled = true; - /** Tags to use when registering management service */ + /** Tags to use when registering management service. */ private List managementTags = new ArrayList<>(); - /** Alternate server path to invoke for health checking */ + /** Alternate server path to invoke for health checking. */ private String healthCheckPath = "/actuator/health"; - /** Custom health check url to override default */ + /** Custom health check url to override default. */ private String healthCheckUrl; - /** Headers to be applied to the Health Check calls */ + /** Headers to be applied to the Health Check calls. */ private Map> healthCheckHeaders = new HashMap<>(); /** How often to perform the health check (e.g. 10s), defaults to 10s. */ @@ -75,24 +75,26 @@ public class ConsulDiscoveryProperties { */ private String healthCheckCriticalTimeout; - /** IP address to use when accessing service (must also set preferIpAddress to use) */ + /** + * IP address to use when accessing service (must also set preferIpAddress to use). + */ private String ipAddress; - /** Hostname to use when accessing server */ + /** Hostname to use when accessing server. */ private String hostname; - /** Port to register the service under (defaults to listening port) */ + /** Port to register the service under (defaults to listening port). */ private Integer port; - /** Port to register the management service under (defaults to management port) */ + /** Port to register the management service under (defaults to management port). */ private Integer managementPort; private Lifecycle lifecycle = new Lifecycle(); - /** Use ip address rather than hostname during registration */ + /** Use ip address rather than hostname during registration. */ private boolean preferIpAddress = false; - /** Source of how we will determine the address to use */ + /** Source of how we will determine the address to use. */ private boolean preferAgentAddress = false; /** The delay between calls to watch consul catalog in millis, default is 1000. */ @@ -101,40 +103,39 @@ public class ConsulDiscoveryProperties { /** The number of seconds to block while watching consul catalog, default is 2. */ private int catalogServicesWatchTimeout = 2; - /** Service name */ + /** Service name. */ private String serviceName; - /** Unique service instance id */ + /** Unique service instance id. */ private String instanceId; - /** Service instance zone */ + /** Service instance zone. */ private String instanceZone; - /** Service instance group*/ + /** Service instance group. */ private String instanceGroup; - /** - * Service instance zone comes from metadata. - * This allows changing the metadata tag name. + * Service instance zone comes from metadata. This allows changing the metadata tag + * name. */ private String defaultZoneMetadataName = "zone"; - /** Whether to register an http or https service */ + /** Whether to register an http or https service. */ private String scheme = "http"; - /** Suffix to use when registering management service */ + /** Suffix to use when registering management service. */ private String managementSuffix = MANAGEMENT; /** - * Map of serviceId's -> tag to query for in server list. - * This allows filtering services by a single tag. + * Map of serviceId's -> tag to query for in server list. This allows filtering + * services by a single tag. */ private Map serverListQueryTags = new HashMap<>(); /** - * Map of serviceId's -> datacenter to query for in server list. - * This allows looking up services in another datacenters. + * Map of serviceId's -> datacenter to query for in server list. This allows looking + * up services in another datacenters. */ private Map datacenters = new HashMap<>(); @@ -142,8 +143,8 @@ public class ConsulDiscoveryProperties { private String defaultQueryTag; /** - * Add the 'passing` parameter to /v1/health/service/serviceName. - * This pushes health check passing to the server. + * Add the 'passing` parameter to /v1/health/service/serviceName. This pushes health + * check passing to the server. */ private boolean queryPassing = false; @@ -157,19 +158,20 @@ public class ConsulDiscoveryProperties { private boolean registerHealthCheck = true; /** - * Throw exceptions during service registration if true, otherwise, log - * warnings (defaults to true). + * Throw exceptions during service registration if true, otherwise, log warnings + * (defaults to true). */ private boolean failFast = true; /** - * Skips certificate verification during service checks if true, otherwise - * runs certificate verification. + * Skips certificate verification during service checks if true, otherwise runs + * certificate verification. */ private Boolean healthCheckTlsSkipVerify; /** - * Order of the discovery client used by `CompositeDiscoveryClient` for sorting available clients. + * Order of the discovery client used by `CompositeDiscoveryClient` for sorting + * available clients. */ private int order = 0; @@ -189,9 +191,9 @@ public class ConsulDiscoveryProperties { * @param serviceId The service who's filtering tag is being looked up * @return The tag the given service id should be filtered by, or null. */ - public String getQueryTagForService(String serviceId){ - String tag = serverListQueryTags.get(serviceId); - return tag != null ? tag : defaultQueryTag; + public String getQueryTagForService(String serviceId) { + String tag = this.serverListQueryTags.get(serviceId); + return tag != null ? tag : this.defaultQueryTag; } public String getHostname() { @@ -203,13 +205,8 @@ public class ConsulDiscoveryProperties { this.hostInfo.override = true; } - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - this.hostInfo.override = true; - } - private HostInfo getHostInfo() { - return hostInfo; + return this.hostInfo; } private void setHostInfo(HostInfo hostInfo) { @@ -217,7 +214,7 @@ public class ConsulDiscoveryProperties { } public String getAclToken() { - return aclToken; + return this.aclToken; } public void setAclToken(String aclToken) { @@ -225,7 +222,7 @@ public class ConsulDiscoveryProperties { } public List getTags() { - return tags; + return this.tags; } public void setTags(List tags) { @@ -233,7 +230,7 @@ public class ConsulDiscoveryProperties { } public boolean isEnabled() { - return enabled; + return this.enabled; } public void setEnabled(boolean enabled) { @@ -241,7 +238,7 @@ public class ConsulDiscoveryProperties { } public List getManagementTags() { - return managementTags; + return this.managementTags; } public void setManagementTags(List managementTags) { @@ -249,7 +246,7 @@ public class ConsulDiscoveryProperties { } public String getHealthCheckPath() { - return healthCheckPath; + return this.healthCheckPath; } public void setHealthCheckPath(String healthCheckPath) { @@ -257,7 +254,7 @@ public class ConsulDiscoveryProperties { } public String getHealthCheckUrl() { - return healthCheckUrl; + return this.healthCheckUrl; } public void setHealthCheckUrl(String healthCheckUrl) { @@ -265,7 +262,7 @@ public class ConsulDiscoveryProperties { } public Map> getHealthCheckHeaders() { - return healthCheckHeaders; + return this.healthCheckHeaders; } public void setHealthCheckHeaders(Map> healthCheckHeaders) { @@ -273,7 +270,7 @@ public class ConsulDiscoveryProperties { } public String getHealthCheckInterval() { - return healthCheckInterval; + return this.healthCheckInterval; } public void setHealthCheckInterval(String healthCheckInterval) { @@ -281,7 +278,7 @@ public class ConsulDiscoveryProperties { } public String getHealthCheckTimeout() { - return healthCheckTimeout; + return this.healthCheckTimeout; } public void setHealthCheckTimeout(String healthCheckTimeout) { @@ -289,7 +286,7 @@ public class ConsulDiscoveryProperties { } public String getHealthCheckCriticalTimeout() { - return healthCheckCriticalTimeout; + return this.healthCheckCriticalTimeout; } public void setHealthCheckCriticalTimeout(String healthCheckCriticalTimeout) { @@ -297,11 +294,16 @@ public class ConsulDiscoveryProperties { } public String getIpAddress() { - return ipAddress; + return this.ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + this.hostInfo.override = true; } public Integer getPort() { - return port; + return this.port; } public void setPort(Integer port) { @@ -309,7 +311,7 @@ public class ConsulDiscoveryProperties { } public Integer getManagementPort() { - return managementPort; + return this.managementPort; } public void setManagementPort(Integer managementPort) { @@ -317,7 +319,7 @@ public class ConsulDiscoveryProperties { } public Lifecycle getLifecycle() { - return lifecycle; + return this.lifecycle; } public void setLifecycle(Lifecycle lifecycle) { @@ -325,7 +327,7 @@ public class ConsulDiscoveryProperties { } public boolean isPreferIpAddress() { - return preferIpAddress; + return this.preferIpAddress; } public void setPreferIpAddress(boolean preferIpAddress) { @@ -333,7 +335,7 @@ public class ConsulDiscoveryProperties { } public boolean isPreferAgentAddress() { - return preferAgentAddress; + return this.preferAgentAddress; } public void setPreferAgentAddress(boolean preferAgentAddress) { @@ -341,7 +343,7 @@ public class ConsulDiscoveryProperties { } public int getCatalogServicesWatchDelay() { - return catalogServicesWatchDelay; + return this.catalogServicesWatchDelay; } public void setCatalogServicesWatchDelay(int catalogServicesWatchDelay) { @@ -349,7 +351,7 @@ public class ConsulDiscoveryProperties { } public int getCatalogServicesWatchTimeout() { - return catalogServicesWatchTimeout; + return this.catalogServicesWatchTimeout; } public void setCatalogServicesWatchTimeout(int catalogServicesWatchTimeout) { @@ -357,7 +359,7 @@ public class ConsulDiscoveryProperties { } public String getServiceName() { - return serviceName; + return this.serviceName; } public void setServiceName(String serviceName) { @@ -365,7 +367,7 @@ public class ConsulDiscoveryProperties { } public String getInstanceId() { - return instanceId; + return this.instanceId; } public void setInstanceId(String instanceId) { @@ -373,7 +375,7 @@ public class ConsulDiscoveryProperties { } public String getInstanceZone() { - return instanceZone; + return this.instanceZone; } public void setInstanceZone(String instanceZone) { @@ -381,7 +383,7 @@ public class ConsulDiscoveryProperties { } public String getInstanceGroup() { - return instanceGroup; + return this.instanceGroup; } public void setInstanceGroup(String instanceGroup) { @@ -389,7 +391,7 @@ public class ConsulDiscoveryProperties { } public String getDefaultZoneMetadataName() { - return defaultZoneMetadataName; + return this.defaultZoneMetadataName; } public void setDefaultZoneMetadataName(String defaultZoneMetadataName) { @@ -397,7 +399,7 @@ public class ConsulDiscoveryProperties { } public String getScheme() { - return scheme; + return this.scheme; } public void setScheme(String scheme) { @@ -405,7 +407,7 @@ public class ConsulDiscoveryProperties { } public String getManagementSuffix() { - return managementSuffix; + return this.managementSuffix; } public void setManagementSuffix(String managementSuffix) { @@ -413,7 +415,7 @@ public class ConsulDiscoveryProperties { } public Map getServerListQueryTags() { - return serverListQueryTags; + return this.serverListQueryTags; } public void setServerListQueryTags(Map serverListQueryTags) { @@ -421,7 +423,7 @@ public class ConsulDiscoveryProperties { } public Map getDatacenters() { - return datacenters; + return this.datacenters; } public void setDatacenters(Map datacenters) { @@ -429,7 +431,7 @@ public class ConsulDiscoveryProperties { } public String getDefaultQueryTag() { - return defaultQueryTag; + return this.defaultQueryTag; } public void setDefaultQueryTag(String defaultQueryTag) { @@ -437,7 +439,7 @@ public class ConsulDiscoveryProperties { } public boolean isQueryPassing() { - return queryPassing; + return this.queryPassing; } public void setQueryPassing(boolean queryPassing) { @@ -445,7 +447,7 @@ public class ConsulDiscoveryProperties { } public boolean isRegister() { - return register; + return this.register; } public void setRegister(boolean register) { @@ -453,7 +455,7 @@ public class ConsulDiscoveryProperties { } public boolean isDeregister() { - return deregister; + return this.deregister; } public void setDeregister(boolean deregister) { @@ -461,7 +463,7 @@ public class ConsulDiscoveryProperties { } public boolean isRegisterHealthCheck() { - return registerHealthCheck; + return this.registerHealthCheck; } public void setRegisterHealthCheck(boolean registerHealthCheck) { @@ -469,7 +471,7 @@ public class ConsulDiscoveryProperties { } public boolean isFailFast() { - return failFast; + return this.failFast; } public void setFailFast(boolean failFast) { @@ -477,7 +479,7 @@ public class ConsulDiscoveryProperties { } public Boolean getHealthCheckTlsSkipVerify() { - return healthCheckTlsSkipVerify; + return this.healthCheckTlsSkipVerify; } public void setHealthCheckTlsSkipVerify(Boolean healthCheckTlsSkipVerify) { @@ -485,7 +487,7 @@ public class ConsulDiscoveryProperties { } public int getOrder() { - return order; + return this.order; } public void setOrder(int order) { @@ -494,52 +496,50 @@ public class ConsulDiscoveryProperties { @Override public String toString() { - return new ToStringCreator(this) - .append("hostInfo", hostInfo) - .append("aclToken", aclToken) - .append("tags", tags) - .append("enabled", enabled) - .append("managementTags", managementTags) - .append("healthCheckPath", healthCheckPath) - .append("healthCheckUrl", healthCheckUrl) - .append("healthCheckHeaders", healthCheckHeaders) - .append("healthCheckInterval", healthCheckInterval) - .append("healthCheckTimeout", healthCheckTimeout) - .append("healthCheckCriticalTimeout", healthCheckCriticalTimeout) - .append("ipAddress", ipAddress) - .append("hostname", hostname) - .append("port", port) - .append("managementPort", managementPort) - .append("lifecycle", lifecycle) - .append("preferIpAddress", preferIpAddress) - .append("preferAgentAddress", preferAgentAddress) - .append("catalogServicesWatchDelay", catalogServicesWatchDelay) - .append("catalogServicesWatchTimeout", catalogServicesWatchTimeout) - .append("serviceName", serviceName) - .append("instanceId", instanceId) - .append("instanceZone", instanceZone) - .append("instanceGroup", instanceGroup) - .append("defaultZoneMetadataName", defaultZoneMetadataName) - .append("scheme", scheme) - .append("managementSuffix", managementSuffix) - .append("serverListQueryTags", serverListQueryTags) - .append("datacenters", datacenters) - .append("defaultQueryTag", defaultQueryTag) - .append("queryPassing", queryPassing) - .append("register", register) - .append("deregister", deregister) - .append("registerHealthCheck", registerHealthCheck) - .append("failFast", failFast) - .append("healthCheckTlsSkipVerify", healthCheckTlsSkipVerify) - .append("order", order) - .toString(); + return new ToStringCreator(this).append("hostInfo", this.hostInfo) + .append("aclToken", this.aclToken).append("tags", this.tags) + .append("enabled", this.enabled) + .append("managementTags", this.managementTags) + .append("healthCheckPath", this.healthCheckPath) + .append("healthCheckUrl", this.healthCheckUrl) + .append("healthCheckHeaders", this.healthCheckHeaders) + .append("healthCheckInterval", this.healthCheckInterval) + .append("healthCheckTimeout", this.healthCheckTimeout) + .append("healthCheckCriticalTimeout", this.healthCheckCriticalTimeout) + .append("ipAddress", this.ipAddress).append("hostname", this.hostname) + .append("port", this.port).append("managementPort", this.managementPort) + .append("lifecycle", this.lifecycle) + .append("preferIpAddress", this.preferIpAddress) + .append("preferAgentAddress", this.preferAgentAddress) + .append("catalogServicesWatchDelay", this.catalogServicesWatchDelay) + .append("catalogServicesWatchTimeout", this.catalogServicesWatchTimeout) + .append("serviceName", this.serviceName) + .append("instanceId", this.instanceId) + .append("instanceZone", this.instanceZone) + .append("instanceGroup", this.instanceGroup) + .append("defaultZoneMetadataName", this.defaultZoneMetadataName) + .append("scheme", this.scheme) + .append("managementSuffix", this.managementSuffix) + .append("serverListQueryTags", this.serverListQueryTags) + .append("datacenters", this.datacenters) + .append("defaultQueryTag", this.defaultQueryTag) + .append("queryPassing", this.queryPassing) + .append("register", this.register).append("deregister", this.deregister) + .append("registerHealthCheck", this.registerHealthCheck) + .append("failFast", this.failFast) + .append("healthCheckTlsSkipVerify", this.healthCheckTlsSkipVerify) + .append("order", this.order).toString(); } + /** + * Properties releated to the lifecycle. + */ public static class Lifecycle { + private boolean enabled = true; public boolean isEnabled() { - return enabled; + return this.enabled; } public void setEnabled(boolean enabled) { @@ -548,9 +548,9 @@ public class ConsulDiscoveryProperties { @Override public String toString() { - return "Lifecycle{" + - "enabled=" + enabled + - '}'; + return "Lifecycle{" + "enabled=" + this.enabled + '}'; } + } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulPing.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulPing.java index 0e660f69..9440404e 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulPing.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulPing.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +20,13 @@ import com.netflix.loadbalancer.IPing; import com.netflix.loadbalancer.Server; /** - * "Ping" Consul - * i.e. we dont do a real "ping". We just assume that the server is up if Consul says so + * "Ping" Consul i.e. we dont do a real "ping". We just assume that the server is up if + * Consul says so + * * @author Spencer Gibb */ public class ConsulPing implements IPing { + @Override public boolean isAlive(Server server) { boolean isAlive = true; @@ -36,4 +38,5 @@ public class ConsulPing implements IPing { return isAlive; } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulRibbonClientConfiguration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulRibbonClientConfiguration.java index 52f3ae21..94130934 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulRibbonClientConfiguration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulRibbonClientConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -47,16 +47,17 @@ import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity */ @Configuration public class ConsulRibbonClientConfiguration { + + protected static final String VALUE_NOT_SET = "__not__set__"; + + protected static final String DEFAULT_NAMESPACE = "ribbon"; + @Autowired private ConsulClient client; @Value("${ribbon.client.name}") private String serviceId = "client"; - protected static final String VALUE_NOT_SET = "__not__set__"; - - protected static final String DEFAULT_NAMESPACE = "ribbon"; - public ConsulRibbonClientConfiguration() { } @@ -66,8 +67,9 @@ public class ConsulRibbonClientConfiguration { @Bean @ConditionalOnMissingBean - public ServerList ribbonServerList(IClientConfig config, ConsulDiscoveryProperties properties) { - ConsulServerList serverList = new ConsulServerList(client, properties); + public ServerList ribbonServerList(IClientConfig config, + ConsulDiscoveryProperties properties) { + ConsulServerList serverList = new ConsulServerList(this.client, properties); serverList.initWithNiwsConfig(config); return serverList; } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServer.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServer.java index 8c4ded7f..3283c3e7 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServer.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -30,17 +30,19 @@ import static org.springframework.cloud.consul.discovery.ConsulServerUtils.findH public class ConsulServer extends Server { private final MetaInfo metaInfo; + private final HealthService service; + private final Map metadata; public ConsulServer(final HealthService healthService) { super(findHost(healthService), healthService.getService().getPort()); this.service = healthService; this.metadata = ConsulServerUtils.getMetadata(this.service); - metaInfo = new MetaInfo() { + this.metaInfo = new MetaInfo() { @Override public String getAppName() { - return service.getService().getService(); + return ConsulServer.this.service.getService().getService(); } @Override @@ -55,7 +57,7 @@ public class ConsulServer extends Server { @Override public String getInstanceId() { - return service.getService().getId(); + return ConsulServer.this.service.getService().getId(); } }; @@ -64,7 +66,7 @@ public class ConsulServer extends Server { @Override public MetaInfo getMetaInfo() { - return metaInfo; + return this.metaInfo; } public HealthService getHealthService() { @@ -72,7 +74,7 @@ public class ConsulServer extends Server { } public Map getMetadata() { - return metadata; + return this.metadata; } public boolean isPassingChecks() { @@ -83,4 +85,5 @@ public class ConsulServer extends Server { } return true; } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerIntrospector.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerIntrospector.java index f607ece1..bd53d1ad 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerIntrospector.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerIntrospector.java @@ -1,10 +1,30 @@ -package org.springframework.cloud.consul.discovery; +/* + * Copyright 2013-2019 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. + */ -import com.netflix.loadbalancer.Server; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; +package org.springframework.cloud.consul.discovery; import java.util.Map; +import com.netflix.loadbalancer.Server; + +import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; + +/** + * @author Spencer Gibb + */ public class ConsulServerIntrospector extends DefaultServerIntrospector { @Override @@ -24,4 +44,5 @@ public class ConsulServerIntrospector extends DefaultServerIntrospector { } return super.getMetadata(server); } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerList.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerList.java index 21653bf7..90693323 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerList.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerList.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -34,6 +34,7 @@ import com.netflix.loadbalancer.AbstractServerList; public class ConsulServerList extends AbstractServerList { private final ConsulClient client; + private final ConsulDiscoveryProperties properties; private String serviceId; @@ -44,15 +45,15 @@ public class ConsulServerList extends AbstractServerList { } protected ConsulClient getClient() { - return client; + return this.client; } protected ConsulDiscoveryProperties getProperties() { - return properties; + return this.properties; } protected String getServiceId() { - return serviceId; + return this.serviceId; } @Override @@ -86,8 +87,8 @@ public class ConsulServerList extends AbstractServerList { /** * Transforms the response from Consul in to a list of usable {@link ConsulServer}s. - * - * @param healthServices the initial list of servers from Consul. Guaranteed to be non-empty list + * @param healthServices the initial list of servers from Consul. Guaranteed to be + * non-empty list * @return ConsulServer instances * @see ConsulServer#ConsulServer(HealthService) */ @@ -95,8 +96,10 @@ public class ConsulServerList extends AbstractServerList { List servers = new ArrayList<>(); for (HealthService service : healthServices) { ConsulServer server = new ConsulServer(service); - if (server.getMetadata().containsKey(this.properties.getDefaultZoneMetadataName())) { - server.setZone(server.getMetadata().get(this.properties.getDefaultZoneMetadataName())); + if (server.getMetadata() + .containsKey(this.properties.getDefaultZoneMetadataName())) { + server.setZone(server.getMetadata() + .get(this.properties.getDefaultZoneMetadataName())); } servers.add(server); } @@ -104,9 +107,9 @@ public class ConsulServerList extends AbstractServerList { } /** - * This method will create the {@link QueryParams} to use when retrieving the - * services from Consul. By default {@link QueryParams#DEFAULT} is used. In case - * a datacenter is specified for the current serviceId {@link QueryParams#datacenter} is set. + * This method will create the {@link QueryParams} to use when retrieving the services + * from Consul. By default {@link QueryParams#DEFAULT} is used. In case a datacenter + * is specified for the current serviceId {@link QueryParams#datacenter} is set. * @return an instance of {@link QueryParams} */ protected QueryParams createQueryParamsForClientRequest() { @@ -128,9 +131,10 @@ public class ConsulServerList extends AbstractServerList { @Override public String toString() { final StringBuilder sb = new StringBuilder("ConsulServerList{"); - sb.append("serviceId='").append(serviceId).append('\''); + sb.append("serviceId='").append(this.serviceId).append('\''); sb.append(", tag=").append(getTag()); sb.append('}'); return sb.toString(); } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerUtils.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerUtils.java index 0a453237..92ab5dca 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerUtils.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -34,17 +34,22 @@ import org.springframework.util.StringUtils; * @author Spencer Gibb * @author Semenkov Alexey */ -public class ConsulServerUtils { +public final class ConsulServerUtils { private static final Log log = LogFactory.getLog(ConsulServerUtils.class); + private ConsulServerUtils() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + public static String findHost(HealthService healthService) { HealthService.Service service = healthService.getService(); HealthService.Node node = healthService.getNode(); if (StringUtils.hasText(service.getAddress())) { return fixIPv6Address(service.getAddress()); - } else if (StringUtils.hasText(node.getAddress())) { + } + else if (StringUtils.hasText(node.getAddress())) { return fixIPv6Address(node.getAddress()); } return node.getNode(); @@ -57,13 +62,13 @@ public class ConsulServerUtils { return "[" + inetAdr.getHostName() + "]"; } return address; - } catch (UnknownHostException e) { + } + catch (UnknownHostException e) { log.debug("Not InetAddress: " + address + " , resolved as is."); return address; } } - public static Map getMetadata(HealthService healthService) { return getMetadata(healthService.getService().getTags()); } @@ -74,18 +79,18 @@ public class ConsulServerUtils { for (String tag : tags) { String[] parts = StringUtils.delimitedListToStringArray(tag, "="); switch (parts.length) { - case 0: - break; - case 1: - metadata.put(parts[0], parts[0]); - break; - case 2: - metadata.put(parts[0], parts[1]); - break; - default: - String[] end = Arrays.copyOfRange(parts, 1, parts.length); - metadata.put(parts[0], StringUtils.arrayToDelimitedString(end, "=")); - break; + case 0: + break; + case 1: + metadata.put(parts[0], parts[0]); + break; + case 2: + metadata.put(parts[0], parts[1]); + break; + default: + String[] end = Arrays.copyOfRange(parts, 1, parts.length); + metadata.put(parts[0], StringUtils.arrayToDelimitedString(end, "=")); + break; } } @@ -93,4 +98,5 @@ public class ConsulServerUtils { return metadata; } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/HealthServiceServerListFilter.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/HealthServiceServerListFilter.java index f04a0af8..8e841ecb 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/HealthServiceServerListFilter.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/HealthServiceServerListFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -25,10 +25,13 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * ServerList implementation that filters ConsulServers based on if all their Health Checks are PASSING. + * ServerList implementation that filters ConsulServers based on if all their Health + * Checks are PASSING. + * * @author Spencer Gibb */ public class HealthServiceServerListFilter implements ServerListFilter { + private static final Log log = LogFactory.getLog(HealthServiceServerListFilter.class); @Override @@ -43,9 +46,11 @@ public class HealthServiceServerListFilter implements ServerListFilter { filtered.add(server); } - } else { - if (log.isDebugEnabled()) { - log.debug("Unable to determine aliveness of server type " + server.getClass() + ", " + server); + } + else { + if (log.isDebugEnabled()) { + log.debug("Unable to determine aliveness of server type " + + server.getClass() + ", " + server); } filtered.add(server); } @@ -53,4 +58,5 @@ public class HealthServiceServerListFilter implements ServerListFilter { return filtered; } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/HeartbeatProperties.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/HeartbeatProperties.java index 1ddb4863..feb1bacc 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/HeartbeatProperties.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/HeartbeatProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -28,11 +28,18 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.style.ToStringCreator; import org.springframework.validation.annotation.Validated; +/** + * Properties related to hearbeat verification. + * + * @author Spencer Gibb + */ @ConfigurationProperties(prefix = "spring.cloud.consul.discovery.heartbeat") @Validated public class HeartbeatProperties { - private static final Log log = org.apache.commons.logging.LogFactory.getLog(HeartbeatProperties.class); + private static final Log log = org.apache.commons.logging.LogFactory + .getLog(HeartbeatProperties.class); + // TODO: change enabled to default to true when I stop seeing messages like // [WARN] agent: Check 'service:testConsulApp:xtest:8080' missed TTL, is now critical boolean enabled = false; @@ -47,63 +54,62 @@ public class HeartbeatProperties { @DecimalMax("0.9") private double intervalRatio = 2.0 / 3.0; - //TODO: did heartbeatInterval need to be a field? + // TODO: did heartbeatInterval need to be a field? - protected Period computeHearbeatInterval() { - // heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser - // priority), no sooner than 1s from now - double interval = ttlValue * intervalRatio; - double max = Math.max(interval, 1); - int ttlMinus1 = ttlValue - 1; - double min = Math.min(ttlMinus1, max); + protected Period computeHearbeatInterval() { + // heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser + // priority), no sooner than 1s from now + double interval = this.ttlValue * this.intervalRatio; + double max = Math.max(interval, 1); + int ttlMinus1 = this.ttlValue - 1; + double min = Math.min(ttlMinus1, max); Period heartbeatInterval = new Period(Math.round(1000 * min)); log.debug("Computed heartbeatInterval: " + heartbeatInterval); return heartbeatInterval; - } + } - public String getTtl() { - return ttlValue + ttlUnit; + public String getTtl() { + return this.ttlValue + this.ttlUnit; } public boolean isEnabled() { return this.enabled; } - public @Min(1) int getTtlValue() { - return this.ttlValue; - } - - public @NotNull String getTtlUnit() { - return this.ttlUnit; - } - - public @DecimalMin("0.1") @DecimalMax("0.9") double getIntervalRatio() { - return this.intervalRatio; - } - public void setEnabled(boolean enabled) { this.enabled = enabled; } + public @Min(1) int getTtlValue() { + return this.ttlValue; + } + public void setTtlValue(@Min(1) int ttlValue) { this.ttlValue = ttlValue; } + public @NotNull String getTtlUnit() { + return this.ttlUnit; + } + public void setTtlUnit(@NotNull String ttlUnit) { this.ttlUnit = ttlUnit; } - public void setIntervalRatio(@DecimalMin("0.1") @DecimalMax("0.9") double intervalRatio) { + public @DecimalMin("0.1") @DecimalMax("0.9") double getIntervalRatio() { + return this.intervalRatio; + } + + public void setIntervalRatio( + @DecimalMin("0.1") @DecimalMax("0.9") double intervalRatio) { this.intervalRatio = intervalRatio; } @Override public String toString() { - return new ToStringCreator(this) - .append("enabled", enabled) - .append("ttlValue", ttlValue) - .append("ttlUnit", ttlUnit) - .append("intervalRatio", intervalRatio) - .toString(); + return new ToStringCreator(this).append("enabled", this.enabled) + .append("ttlValue", this.ttlValue).append("ttlUnit", this.ttlUnit) + .append("intervalRatio", this.intervalRatio).toString(); } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/RibbonConsulAutoConfiguration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/RibbonConsulAutoConfiguration.java index d43512d4..dc62a427 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/RibbonConsulAutoConfiguration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/RibbonConsulAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2019 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. diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/TestConsulLifecycleConfiguration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/TestConsulLifecycleConfiguration.java deleted file mode 100644 index e69de29b..00000000 diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/TtlScheduler.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/TtlScheduler.java index 67a8e482..3c373aee 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/TtlScheduler.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/TtlScheduler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -31,9 +31,11 @@ import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; /** * Created by nicu on 11.03.2015. + * * @author Stéphane LEROY */ public class TtlScheduler { + private static final Log log = LogFactory.getLog(ConsulDiscoveryClient.class); private final Map serviceHeartbeats = new ConcurrentHashMap<>(); @@ -57,41 +59,45 @@ public class TtlScheduler { /** * Add a service to the checks loop. + * @param instanceId instance id */ public void add(String instanceId) { - ScheduledFuture task = scheduler.scheduleAtFixedRate(new ConsulHeartbeatTask( - instanceId), configuration.computeHearbeatInterval() - .toStandardDuration().getMillis()); - ScheduledFuture previousTask = serviceHeartbeats.put(instanceId, task); + ScheduledFuture task = this.scheduler.scheduleAtFixedRate( + new ConsulHeartbeatTask(instanceId), this.configuration + .computeHearbeatInterval().toStandardDuration().getMillis()); + ScheduledFuture previousTask = this.serviceHeartbeats.put(instanceId, task); if (previousTask != null) { previousTask.cancel(true); } } public void remove(String instanceId) { - ScheduledFuture task = serviceHeartbeats.get(instanceId); + ScheduledFuture task = this.serviceHeartbeats.get(instanceId); if (task != null) { task.cancel(true); } - serviceHeartbeats.remove(instanceId); + this.serviceHeartbeats.remove(instanceId); } private class ConsulHeartbeatTask implements Runnable { + private String checkId; ConsulHeartbeatTask(String serviceId) { this.checkId = serviceId; - if (!checkId.startsWith("service:")) { - checkId = "service:" + checkId; + if (!this.checkId.startsWith("service:")) { + this.checkId = "service:" + this.checkId; } } @Override public void run() { - client.agentCheckPass(checkId); + TtlScheduler.this.client.agentCheckPass(this.checkId); if (log.isDebugEnabled()) { - log.debug("Sending consul heartbeat for: " + checkId); + log.debug("Sending consul heartbeat for: " + this.checkId); } } + } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfiguration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfiguration.java index 833c3d38..9e515d03 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfiguration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,6 +18,8 @@ package org.springframework.cloud.consul.discovery.configclient; import javax.annotation.PostConstruct; +import com.ecwid.consul.v1.ConsulClient; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -26,8 +28,6 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; -import com.ecwid.consul.v1.ConsulClient; - /** * Extra configuration for config server if it happens to be registered with Consul. * @@ -52,7 +52,7 @@ public class ConsulConfigServerAutoConfiguration { } String prefix = this.server.getPrefix(); if (StringUtils.hasText(prefix)) { - this.properties.getTags().add("configPath="+prefix); + this.properties.getTags().add("configPath=" + prefix); } } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulDiscoveryClientConfigServiceBootstrapConfiguration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulDiscoveryClientConfigServiceBootstrapConfiguration.java index 9dff098c..0535cf99 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulDiscoveryClientConfigServiceBootstrapConfiguration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulDiscoveryClientConfigServiceBootstrapConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-2019 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. @@ -32,7 +32,8 @@ import org.springframework.context.annotation.Configuration; @ConditionalOnClass(ConfigServicePropertySourceLocator.class) @ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false) @Configuration -@ImportAutoConfiguration({ ConsulAutoConfiguration.class, ConsulDiscoveryClientConfiguration.class}) +@ImportAutoConfiguration({ ConsulAutoConfiguration.class, + ConsulDiscoveryClientConfiguration.class }) public class ConsulDiscoveryClientConfigServiceBootstrapConfiguration { } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/AliveServerListFilter.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/AliveServerListFilter.java index c98267e8..ee49dd9a 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/AliveServerListFilter.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/AliveServerListFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,21 +20,23 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; -import org.springframework.cloud.consul.discovery.ConsulServer; - import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerListFilter; +import org.springframework.cloud.consul.discovery.ConsulServer; + /** * Server filter: returns only alive servers. Each consul agent runs a serf agent which is * a member of the serf gossip pool. The serf status (alive/failed/etc) is reflected in 2 * consul APIs: in the agent API and in the catalog API. We prefer the agent API because * it is most up to date (or perhaps we should intersect them and pick members that are * live in both). + * * @author nicu marasoiu on 10.03.2015. */ @Deprecated public class AliveServerListFilter implements ServerListFilter { + private FilteringAgentClient filteringAgentClient; public AliveServerListFilter(FilteringAgentClient filteringAgentClient) { @@ -43,14 +45,16 @@ public class AliveServerListFilter implements ServerListFilter { @Override public List getFilteredListOfServers(List servers) { - Set liveNodes = filteringAgentClient.getAliveAgentsAddresses(); + Set liveNodes = this.filteringAgentClient.getAliveAgentsAddresses(); List filteredServers = new ArrayList<>(); for (Server server : servers) { ConsulServer consulServer = ConsulServer.class.cast(server); - if (liveNodes.contains(consulServer.getHealthService().getService().getAddress())) { + if (liveNodes.contains( + consulServer.getHealthService().getService().getAddress())) { filteredServers.add(server); } } return filteredServers; } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/FilteringAgentClient.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/FilteringAgentClient.java index 37ea304c..825f16ec 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/FilteringAgentClient.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/FilteringAgentClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,14 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.springframework.cloud.consul.model.SerfStatusEnum; - import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.agent.model.Member; +import org.springframework.cloud.consul.model.SerfStatusEnum; + +/** + * @author Nicu Marasoiu + */ @Deprecated public class FilteringAgentClient { @@ -38,7 +41,7 @@ public class FilteringAgentClient { } public List getAliveAgents() { - List members = client.getAgentMembers().getValue(); + List members = this.client.getAgentMembers().getValue(); List liveMembers = new ArrayList<>(members.size()); for (Member peer : members) { if (peer.getStatus() == ALIVE_STATUS) { @@ -55,4 +58,5 @@ public class FilteringAgentClient { } return addresses; } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/ServiceCheckServerListFilter.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/ServiceCheckServerListFilter.java index 7449cc97..cbca3c79 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/ServiceCheckServerListFilter.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/filters/ServiceCheckServerListFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -27,6 +27,8 @@ import com.netflix.loadbalancer.ServerListFilter; /** * Created by nicu on 12.03.2015. + * + * @author Nicu Marasoiu */ @Deprecated public class ServiceCheckServerListFilter implements ServerListFilter { @@ -44,9 +46,9 @@ public class ServiceCheckServerListFilter implements ServerListFilter { for (Server server : servers) { String appName = server.getMetaInfo().getAppName(); String instanceId = server.getMetaInfo().getInstanceId(); - //TODO: cache getHealthChecks? this is hit often - List serviceChecks = client.getHealthChecksForService(appName, - QueryParams.DEFAULT).getValue(); + // TODO: cache getHealthChecks? this is hit often + List serviceChecks = this.client + .getHealthChecksForService(appName, QueryParams.DEFAULT).getValue(); boolean serviceOk = true; for (Check check : serviceChecks) { if (check.getServiceId().equals(instanceId) diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistration.java index 4d5bcb95..e2ae41d2 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistration.java @@ -20,6 +20,8 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import com.ecwid.consul.v1.agent.model.NewService; + import org.springframework.cloud.client.discovery.ManagementServerPortUtils; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; @@ -31,29 +33,38 @@ import org.springframework.core.env.Environment; import org.springframework.util.Assert; import org.springframework.util.StringUtils; -import com.ecwid.consul.v1.agent.model.NewService; - /** * @author Spencer Gibb */ public class ConsulAutoRegistration extends ConsulRegistration { + /** + * Instance ID separator. + */ public static final char SEPARATOR = '-'; private final AutoServiceRegistrationProperties autoServiceRegistrationProperties; + private final ApplicationContext context; + private final HeartbeatProperties heartbeatProperties; + private final List managementRegistrationCustomizers; @Deprecated - public ConsulAutoRegistration(NewService service, AutoServiceRegistrationProperties autoServiceRegistrationProperties, - ConsulDiscoveryProperties properties, ApplicationContext context, HeartbeatProperties heartbeatProperties) { - this(service, autoServiceRegistrationProperties, properties, context, heartbeatProperties, Collections.emptyList()); + public ConsulAutoRegistration(NewService service, + AutoServiceRegistrationProperties autoServiceRegistrationProperties, + ConsulDiscoveryProperties properties, ApplicationContext context, + HeartbeatProperties heartbeatProperties) { + this(service, autoServiceRegistrationProperties, properties, context, + heartbeatProperties, Collections.emptyList()); } - public ConsulAutoRegistration(NewService service, AutoServiceRegistrationProperties autoServiceRegistrationProperties, - ConsulDiscoveryProperties properties, ApplicationContext context, HeartbeatProperties heartbeatProperties, - List managementRegistrationCustomizers) { + public ConsulAutoRegistration(NewService service, + AutoServiceRegistrationProperties autoServiceRegistrationProperties, + ConsulDiscoveryProperties properties, ApplicationContext context, + HeartbeatProperties heartbeatProperties, + List managementRegistrationCustomizers) { super(service, properties); this.autoServiceRegistrationProperties = autoServiceRegistrationProperties; this.context = context; @@ -61,24 +72,8 @@ public class ConsulAutoRegistration extends ConsulRegistration { this.managementRegistrationCustomizers = managementRegistrationCustomizers; } - public void initializePort(int knownPort) { - if (getService().getPort() == null) { - // not set by properties - getService().setPort(knownPort); - } - // we might not have a port until now, so this is the earliest we - // can create a check - - setCheck(getService(), this.autoServiceRegistrationProperties, getProperties(), - this.context, this.heartbeatProperties); - } - - public ConsulAutoRegistration managementRegistration() { - return managementRegistration(this.autoServiceRegistrationProperties, getProperties(), - this.context, this.managementRegistrationCustomizers, this.heartbeatProperties); - } - - public static ConsulAutoRegistration registration(AutoServiceRegistrationProperties autoServiceRegistrationProperties, + public static ConsulAutoRegistration registration( + AutoServiceRegistrationProperties autoServiceRegistrationProperties, ConsulDiscoveryProperties properties, ApplicationContext context, List registrationCustomizers, List managementRegistrationCustomizers, @@ -87,7 +82,7 @@ public class ConsulAutoRegistration extends ConsulRegistration { NewService service = new NewService(); String appName = getAppName(properties, context.getEnvironment()); service.setId(getInstanceId(properties, context)); - if(!properties.isPreferAgentAddress()) { + if (!properties.isPreferAgentAddress()) { service.setAddress(properties.getHostname()); } service.setName(normalizeForDns(appName)); @@ -96,16 +91,20 @@ public class ConsulAutoRegistration extends ConsulRegistration { if (properties.getPort() != null) { service.setPort(properties.getPort()); // we know the port and can set the check - setCheck(service, autoServiceRegistrationProperties, properties, context, heartbeatProperties); + setCheck(service, autoServiceRegistrationProperties, properties, context, + heartbeatProperties); } - ConsulAutoRegistration registration = new ConsulAutoRegistration(service, autoServiceRegistrationProperties, - properties, context, heartbeatProperties, managementRegistrationCustomizers); + ConsulAutoRegistration registration = new ConsulAutoRegistration(service, + autoServiceRegistrationProperties, properties, context, + heartbeatProperties, managementRegistrationCustomizers); customize(registrationCustomizers, registration); return registration; } - public static void customize(List registrationCustomizers, ConsulAutoRegistration registration) { + public static void customize( + List registrationCustomizers, + ConsulAutoRegistration registration) { if (registrationCustomizers != null) { for (ConsulRegistrationCustomizer customizer : registrationCustomizers) { customizer.customize(registration); @@ -119,9 +118,11 @@ public class ConsulAutoRegistration extends ConsulRegistration { HeartbeatProperties heartbeatProperties) { if (properties.isRegisterHealthCheck() && service.getCheck() == null) { Integer checkPort; - if (shouldRegisterManagement(autoServiceRegistrationProperties, properties, context)) { + if (shouldRegisterManagement(autoServiceRegistrationProperties, properties, + context)) { checkPort = getManagementPort(properties, context); - } else { + } + else { checkPort = service.getPort(); } Assert.notNull(checkPort, "checkPort may not be null"); @@ -137,18 +138,24 @@ public class ConsulAutoRegistration extends ConsulRegistration { NewService management = new NewService(); management.setId(getManagementServiceId(properties, context)); management.setAddress(properties.getHostname()); - management.setName(getManagementServiceName(properties, context.getEnvironment())); + management + .setName(getManagementServiceName(properties, context.getEnvironment())); management.setPort(getManagementPort(properties, context)); management.setTags(properties.getManagementTags()); if (properties.isRegisterHealthCheck()) { - management.setCheck(createCheck(getManagementPort(properties, context), heartbeatProperties, properties)); + management.setCheck(createCheck(getManagementPort(properties, context), + heartbeatProperties, properties)); } - ConsulAutoRegistration registration = new ConsulAutoRegistration(management, autoServiceRegistrationProperties, properties, context, heartbeatProperties, managementRegistrationCustomizers); + ConsulAutoRegistration registration = new ConsulAutoRegistration(management, + autoServiceRegistrationProperties, properties, context, + heartbeatProperties, managementRegistrationCustomizers); managementCustomize(managementRegistrationCustomizers, registration); return registration; } - public static void managementCustomize(List registrationCustomizers, ConsulAutoRegistration registration) { + public static void managementCustomize( + List registrationCustomizers, + ConsulAutoRegistration registration) { if (registrationCustomizers != null) { for (ConsulManagementRegistrationCustomizer customizer : registrationCustomizers) { customizer.customize(registration); @@ -156,17 +163,23 @@ public class ConsulAutoRegistration extends ConsulRegistration { } } - public static String getInstanceId(ConsulDiscoveryProperties properties, ApplicationContext context) { + public static String getInstanceId(ConsulDiscoveryProperties properties, + ApplicationContext context) { if (!StringUtils.hasText(properties.getInstanceId())) { - return normalizeForDns(IdUtils.getDefaultInstanceId(context.getEnvironment(), false)); + return normalizeForDns( + IdUtils.getDefaultInstanceId(context.getEnvironment(), false)); } return normalizeForDns(properties.getInstanceId()); } public static String normalizeForDns(String s) { if (s == null || !Character.isLetter(s.charAt(0)) - || !Character.isLetterOrDigit(s.charAt(s.length()-1))) { - throw new IllegalArgumentException("Consul service ids must not be empty, must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen: "+s); + || !Character.isLetterOrDigit(s.charAt(s.length() - 1))) { + throw new IllegalArgumentException( + "Consul service ids must not be empty, must start " + + "with a letter, end with a letter or digit, " + + "and have as interior characters only letters, " + + "digits, and hyphen: " + s); } StringBuilder normalized = new StringBuilder(); @@ -175,7 +188,8 @@ public class ConsulAutoRegistration extends ConsulRegistration { Character toAppend = null; if (Character.isLetterOrDigit(curr)) { toAppend = curr; - } else if (prev == null || !(prev == SEPARATOR)) { + } + else if (prev == null || !(prev == SEPARATOR)) { toAppend = SEPARATOR; } if (toAppend != null) { @@ -191,20 +205,23 @@ public class ConsulAutoRegistration extends ConsulRegistration { List tags = new LinkedList<>(properties.getTags()); if (!StringUtils.isEmpty(properties.getInstanceZone())) { - tags.add(properties.getDefaultZoneMetadataName() + "=" + properties.getInstanceZone()); + tags.add(properties.getDefaultZoneMetadataName() + "=" + + properties.getInstanceZone()); } if (!StringUtils.isEmpty(properties.getInstanceGroup())) { tags.add("group=" + properties.getInstanceGroup()); } - //store the secure flag in the tags so that clients will be able to figure out whether to use http or https automatically - tags.add("secure=" + Boolean.toString(properties.getScheme().equalsIgnoreCase("https"))); + // store the secure flag in the tags so that clients will be able to figure out + // whether to use http or https automatically + tags.add("secure=" + + Boolean.toString(properties.getScheme().equalsIgnoreCase("https"))); return tags; } - public static NewService.Check createCheck(Integer port, HeartbeatProperties ttlConfig, - ConsulDiscoveryProperties properties) { + public static NewService.Check createCheck(Integer port, + HeartbeatProperties ttlConfig, ConsulDiscoveryProperties properties) { NewService.Check check = new NewService.Check(); if (ttlConfig.isEnabled()) { check.setTtl(ttlConfig.getTtl()); @@ -216,25 +233,29 @@ public class ConsulAutoRegistration extends ConsulRegistration { if (properties.getHealthCheckUrl() != null) { check.setHttp(properties.getHealthCheckUrl()); - } else { + } + else { check.setHttp(String.format("%s://%s:%s%s", properties.getScheme(), - properties.getHostname(), port, - properties.getHealthCheckPath())); + properties.getHostname(), port, properties.getHealthCheckPath())); } check.setHeader(properties.getHealthCheckHeaders()); check.setInterval(properties.getHealthCheckInterval()); check.setTimeout(properties.getHealthCheckTimeout()); if (StringUtils.hasText(properties.getHealthCheckCriticalTimeout())) { - check.setDeregisterCriticalServiceAfter(properties.getHealthCheckCriticalTimeout()); + check.setDeregisterCriticalServiceAfter( + properties.getHealthCheckCriticalTimeout()); } check.setTlsSkipVerify(properties.getHealthCheckTlsSkipVerify()); return check; } /** + * @param properties consul discovery properties + * @param env Spring environment * @return the app name, currently the spring.application.name property */ - public static String getAppName(ConsulDiscoveryProperties properties, Environment env) { + public static String getAppName(ConsulDiscoveryProperties properties, + Environment env) { final String appName = properties.getServiceName(); if (StringUtils.hasText(appName)) { return appName; @@ -243,44 +264,83 @@ public class ConsulAutoRegistration extends ConsulRegistration { } /** - * @return if the management service should be registered with the {@link ServiceRegistry} + * @param autoServiceRegistrationProperties registration properties + * @param properties discovery properties + * @param context Spring application context + * @return if the management service should be registered with the + * {@link ServiceRegistry} */ - public static boolean shouldRegisterManagement(AutoServiceRegistrationProperties autoServiceRegistrationProperties, ConsulDiscoveryProperties properties, ApplicationContext context) { + public static boolean shouldRegisterManagement( + AutoServiceRegistrationProperties autoServiceRegistrationProperties, + ConsulDiscoveryProperties properties, ApplicationContext context) { return autoServiceRegistrationProperties.isRegisterManagement() && getManagementPort(properties, context) != null && ManagementServerPortUtils.isDifferent(context); } /** + * @param properties discovery properties + * @param context Spring application context * @return the serviceId of the Management Service */ - public static String getManagementServiceId(ConsulDiscoveryProperties properties, ApplicationContext context) { + public static String getManagementServiceId(ConsulDiscoveryProperties properties, + ApplicationContext context) { final String instanceId = properties.getInstanceId(); if (StringUtils.hasText(instanceId)) { - return normalizeForDns(instanceId + SEPARATOR + properties.getManagementSuffix()); + return normalizeForDns( + instanceId + SEPARATOR + properties.getManagementSuffix()); } - return normalizeForDns(IdUtils.getDefaultInstanceId(context.getEnvironment(), false)) + SEPARATOR + properties.getManagementSuffix(); + return normalizeForDns( + IdUtils.getDefaultInstanceId(context.getEnvironment(), false)) + SEPARATOR + + properties.getManagementSuffix(); } /** + * @param properties discovery properties + * @param env Spring environment * @return the service name of the Management Service */ - public static String getManagementServiceName(ConsulDiscoveryProperties properties, Environment env) { + public static String getManagementServiceName(ConsulDiscoveryProperties properties, + Environment env) { final String appName = properties.getServiceName(); if (StringUtils.hasText(appName)) { - return normalizeForDns(appName + SEPARATOR + properties.getManagementSuffix()); + return normalizeForDns( + appName + SEPARATOR + properties.getManagementSuffix()); } - return normalizeForDns(getAppName(properties, env)) + SEPARATOR + properties.getManagementSuffix(); + return normalizeForDns(getAppName(properties, env)) + SEPARATOR + + properties.getManagementSuffix(); } /** + * @param properties discovery properties + * @param context Spring application context * @return the port of the Management Service */ - public static Integer getManagementPort(ConsulDiscoveryProperties properties, ApplicationContext context) { + public static Integer getManagementPort(ConsulDiscoveryProperties properties, + ApplicationContext context) { // If an alternate external port is specified, use it instead if (properties.getManagementPort() != null) { return properties.getManagementPort(); } return ManagementServerPortUtils.getPort(context); } + + public void initializePort(int knownPort) { + if (getService().getPort() == null) { + // not set by properties + getService().setPort(knownPort); + } + // we might not have a port until now, so this is the earliest we + // can create a check + + setCheck(getService(), this.autoServiceRegistrationProperties, getProperties(), + this.context, this.heartbeatProperties); + } + + public ConsulAutoRegistration managementRegistration() { + return managementRegistration(this.autoServiceRegistrationProperties, + getProperties(), this.context, this.managementRegistrationCustomizers, + this.heartbeatProperties); + } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistration.java index 5d31aa2f..1ad76254 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,6 +18,7 @@ package org.springframework.cloud.consul.serviceregistry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; @@ -29,11 +30,13 @@ import org.springframework.util.StringUtils; /** * @author Spencer Gibb */ -public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistration { +public class ConsulAutoServiceRegistration + extends AbstractAutoServiceRegistration { private static Log log = LogFactory.getLog(ConsulAutoServiceRegistration.class); private ConsulDiscoveryProperties properties; + private ConsulAutoRegistration registration; public ConsulAutoServiceRegistration(ConsulServiceRegistry serviceRegistry, @@ -50,10 +53,12 @@ public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistrati @Override protected ConsulAutoRegistration getRegistration() { - if (this.registration.getService().getPort() == null && this.getPort().get() > 0) { + if (this.registration.getService().getPort() == null + && this.getPort().get() > 0) { this.registration.initializePort(this.getPort().get()); } - Assert.notNull(this.registration.getService().getPort(), "service.port has not been set"); + Assert.notNull(this.registration.getService().getPort(), + "service.port has not been set"); return this.registration; } @@ -89,7 +94,7 @@ public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistrati @Override protected Object getConfiguration() { - return properties; + return this.properties; } @Override @@ -116,7 +121,7 @@ public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistrati @Override @SuppressWarnings("deprecation") protected String getAppName() { - String appName = properties.getServiceName(); + String appName = this.properties.getServiceName(); return StringUtils.isEmpty(appName) ? super.getAppName() : appName; } @@ -125,4 +130,5 @@ public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistrati // do nothing so we can listen for this event in a different class // this ensures start() can be retried if spring-retry is available } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationAutoConfiguration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationAutoConfiguration.java index 56bac0d9..931a3623 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationAutoConfiguration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationAutoConfiguration.java @@ -44,7 +44,8 @@ import org.springframework.context.annotation.Configuration; @ConditionalOnMissingBean(type = "org.springframework.cloud.consul.discovery.ConsulLifecycle") @ConditionalOnConsulEnabled @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) -@AutoConfigureAfter({AutoServiceRegistrationConfiguration.class, ConsulServiceRegistryAutoConfiguration.class}) +@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class, + ConsulServiceRegistryAutoConfiguration.class }) public class ConsulAutoServiceRegistrationAutoConfiguration { @Autowired @@ -62,31 +63,34 @@ public class ConsulAutoServiceRegistrationAutoConfiguration { } @Bean - public ConsulAutoServiceRegistrationListener consulAutoServiceRegistrationListener(ConsulAutoServiceRegistration registration) { + public ConsulAutoServiceRegistrationListener consulAutoServiceRegistrationListener( + ConsulAutoServiceRegistration registration) { return new ConsulAutoServiceRegistrationListener(registration); } @Bean @ConditionalOnMissingBean - public ConsulAutoRegistration consulRegistration(AutoServiceRegistrationProperties autoServiceRegistrationProperties, + public ConsulAutoRegistration consulRegistration( + AutoServiceRegistrationProperties autoServiceRegistrationProperties, ConsulDiscoveryProperties properties, ApplicationContext applicationContext, ObjectProvider> registrationCustomizers, ObjectProvider> managementRegistrationCustomizers, HeartbeatProperties heartbeatProperties) { - return ConsulAutoRegistration.registration(autoServiceRegistrationProperties, properties, - applicationContext, registrationCustomizers.getIfAvailable(), - managementRegistrationCustomizers.getIfAvailable(), - heartbeatProperties); + return ConsulAutoRegistration.registration(autoServiceRegistrationProperties, + properties, applicationContext, registrationCustomizers.getIfAvailable(), + managementRegistrationCustomizers.getIfAvailable(), heartbeatProperties); } @Configuration @ConditionalOnClass(ServletContext.class) protected static class ConsulServletConfiguration { + @Bean - public ConsulRegistrationCustomizer servletConsulCustomizer(ObjectProvider servletContext) { + public ConsulRegistrationCustomizer servletConsulCustomizer( + ObjectProvider servletContext) { return new ConsulServletRegistrationCustomizer(servletContext); } + } - } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationListener.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationListener.java index 765916d7..b085c3b2 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationListener.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationListener.java @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2019 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.consul.serviceregistry; import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; @@ -6,10 +22,17 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEvent; import org.springframework.context.event.SmartApplicationListener; +/** + * Auto registers service upon web server initialization. + * + * @author Spencer Gibb + */ public class ConsulAutoServiceRegistrationListener implements SmartApplicationListener { + private final ConsulAutoServiceRegistration autoServiceRegistration; - public ConsulAutoServiceRegistrationListener(ConsulAutoServiceRegistration autoServiceRegistration) { + public ConsulAutoServiceRegistrationListener( + ConsulAutoServiceRegistration autoServiceRegistration) { this.autoServiceRegistration = autoServiceRegistration; } @@ -30,8 +53,9 @@ public class ConsulAutoServiceRegistrationListener implements SmartApplicationLi ApplicationContext context = event.getApplicationContext(); if (context instanceof ConfigurableWebServerApplicationContext) { - if ("management".equals( - ((ConfigurableWebServerApplicationContext) context).getServerNamespace())) { + if ("management" + .equals(((ConfigurableWebServerApplicationContext) context) + .getServerNamespace())) { return; } } @@ -44,4 +68,5 @@ public class ConsulAutoServiceRegistrationListener implements SmartApplicationLi public int getOrder() { return 0; } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulManagementRegistrationCustomizer.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulManagementRegistrationCustomizer.java index 28ad9b57..605ac333 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulManagementRegistrationCustomizer.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulManagementRegistrationCustomizer.java @@ -20,5 +20,11 @@ package org.springframework.cloud.consul.serviceregistry; * @author Alexey Savchuk (devpreview) */ public interface ConsulManagementRegistrationCustomizer { + + /** + * Customizes a registration. + * @param managementRegistration registration to customize + */ void customize(ConsulRegistration managementRegistration); + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistration.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistration.java index ade8e615..614ce9df 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistration.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,22 +16,23 @@ package org.springframework.cloud.consul.serviceregistry; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.serviceregistry.Registration; - -import com.ecwid.consul.v1.agent.model.NewService; -import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; -import org.springframework.cloud.consul.discovery.ConsulServerUtils; - import java.net.URI; import java.util.Map; +import com.ecwid.consul.v1.agent.model.NewService; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; +import org.springframework.cloud.consul.discovery.ConsulServerUtils; + /** * @author Spencer Gibb */ public class ConsulRegistration implements Registration { private final NewService service; + private ConsulDiscoveryProperties properties; public ConsulRegistration(NewService service, ConsulDiscoveryProperties properties) { @@ -40,11 +41,11 @@ public class ConsulRegistration implements Registration { } public NewService getService() { - return service; + return this.service; } protected ConsulDiscoveryProperties getProperties() { - return properties; + return this.properties; } public String getInstanceId() { @@ -79,4 +80,5 @@ public class ConsulRegistration implements Registration { public Map getMetadata() { return ConsulServerUtils.getMetadata(getService().getTags()); } + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistrationCustomizer.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistrationCustomizer.java index 2496e313..fe932f48 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistrationCustomizer.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistrationCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,5 +20,7 @@ package org.springframework.cloud.consul.serviceregistry; * @author Piotr Wielgolaski */ public interface ConsulRegistrationCustomizer { + void customize(ConsulRegistration registration); + } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistry.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistry.java index c842d34f..6bac930c 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistry.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,21 +18,21 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.List; +import com.ecwid.consul.ConsulException; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.QueryParams; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.NewService; +import com.ecwid.consul.v1.health.model.Check; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.cloud.consul.discovery.HeartbeatProperties; import org.springframework.cloud.consul.discovery.TtlScheduler; import org.springframework.util.ReflectionUtils; -import com.ecwid.consul.ConsulException; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.QueryParams; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.health.model.Check; -import com.ecwid.consul.v1.agent.model.NewService; - import static org.springframework.boot.actuate.health.Status.OUT_OF_SERVICE; import static org.springframework.boot.actuate.health.Status.UP; @@ -51,7 +51,9 @@ public class ConsulServiceRegistry implements ServiceRegistry> response = client.getHealthChecksForService(serviceId, QueryParams.DEFAULT); + Response> response = this.client.getHealthChecksForService(serviceId, + QueryParams.DEFAULT); List checks = response.getValue(); for (Check check : checks) { @@ -121,4 +132,5 @@ public class ConsulServiceRegistry implements ServiceRegistry servletContext; - public ConsulServletRegistrationCustomizer(ObjectProvider servletContext) { + public ConsulServletRegistrationCustomizer( + ObjectProvider servletContext) { this.servletContext = servletContext; } @Override public void customize(ConsulRegistration registration) { - if (servletContext == null) { + if (this.servletContext == null) { return; } - ServletContext sc = servletContext.getIfAvailable(); - if(sc != null - && StringUtils.hasText(sc.getContextPath()) + ServletContext sc = this.servletContext.getIfAvailable(); + if (sc != null && StringUtils.hasText(sc.getContextPath()) && StringUtils.hasText(sc.getContextPath().replaceAll("/", ""))) { List tags = registration.getService().getTags(); if (tags == null) { @@ -50,4 +52,5 @@ public class ConsulServletRegistrationCustomizer implements ConsulRegistrationCu registration.getService().setTags(tags); } } + } diff --git a/spring-cloud-consul-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-consul-discovery/src/main/resources/META-INF/spring.factories index d1d8101c..bb5f5e48 100644 --- a/spring-cloud-consul-discovery/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-consul-discovery/src/main/resources/META-INF/spring.factories @@ -4,8 +4,6 @@ org.springframework.cloud.consul.discovery.configclient.ConsulConfigServerAutoCo org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration,\ org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration,\ org.springframework.cloud.consul.discovery.ConsulDiscoveryClientConfiguration - - org.springframework.cloud.bootstrap.BootstrapConfiguration=\ org.springframework.cloud.consul.discovery.configclient.ConsulDiscoveryClientConfigServiceBootstrapConfiguration diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientAclTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientAclTests.java index 5deaef0a..d83d3f79 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientAclTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientAclTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -29,19 +30,17 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulDiscoveryClientAclTests.MyTestConfig.class, - properties = {"spring.application.name=testConsulDiscoveryAcl", - "spring.cloud.consul.discovery.preferIpAddress=true", - "consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304"}, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = ConsulDiscoveryClientAclTests.MyTestConfig.class, properties = { + "spring.application.name=testConsulDiscoveryAcl", + "spring.cloud.consul.discovery.preferIpAddress=true", + "consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304" }, webEnvironment = RANDOM_PORT) public class ConsulDiscoveryClientAclTests { @Autowired @@ -49,24 +48,25 @@ public class ConsulDiscoveryClientAclTests { @Test public void getInstancesForThisServiceWorks() { - List instances = discoveryClient.getInstances("testConsulDiscoveryAcl"); - assertNotNull("instances was null", instances); - assertFalse("instances was empty", instances.isEmpty()); + List instances = this.discoveryClient + .getInstances("testConsulDiscoveryAcl"); + assertThat(instances).as("instances was null").isNotNull(); + assertThat(instances.isEmpty()).as("instances was empty").isFalse(); } - @Test public void getInstancesForSecondServiceWorks() throws Exception { - new SpringApplicationBuilder(MyTestConfig.class) - .run("--spring.application.name=testSecondServiceAcl", - "--server.port=0", - "--spring.cloud.consul.discovery.preferIpAddress=true", - "--consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304"); + new SpringApplicationBuilder(MyTestConfig.class).run( + "--spring.application.name=testSecondServiceAcl", "--server.port=0", + "--spring.cloud.consul.discovery.preferIpAddress=true", + "--consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304"); - List instances = discoveryClient.getInstances("testSecondServiceAcl"); - assertNotNull("second service instances was null", instances); - assertFalse("second service instances was empty", instances.isEmpty()); + List instances = this.discoveryClient + .getInstances("testSecondServiceAcl"); + assertThat(instances).as("second service instances was null").isNotNull(); + assertThat(instances.isEmpty()).as("second service instances was empty") + .isFalse(); } @Configuration @@ -75,4 +75,5 @@ public class ConsulDiscoveryClientAclTests { public static class MyTestConfig { } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientCustomizedTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientCustomizedTests.java index 1bf77f80..1eded26b 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientCustomizedTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientCustomizedTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-2019 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. @@ -22,6 +22,7 @@ import java.util.Map; import org.apache.http.conn.util.InetAddressUtils; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -30,9 +31,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** @@ -40,13 +39,12 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author Tim Ysewyn */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulDiscoveryClientCustomizedTests.MyTestConfig.class, - properties = { "spring.application.name=testConsulDiscovery2", +@SpringBootTest(classes = ConsulDiscoveryClientCustomizedTests.MyTestConfig.class, properties = { + "spring.application.name=testConsulDiscovery2", "spring.cloud.consul.discovery.instanceId=testConsulDiscovery2Id", "spring.cloud.consul.discovery.hostname=testConsulDiscovery2Host", "spring.cloud.consul.discovery.registerHealthCheck=false", - "spring.cloud.consul.discovery.tags=plaintag,foo=bar,foo2=bar2=baz2" }, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.tags=plaintag,foo=bar,foo2=bar2=baz2" }, webEnvironment = RANDOM_PORT) public class ConsulDiscoveryClientCustomizedTests { @Autowired @@ -54,42 +52,44 @@ public class ConsulDiscoveryClientCustomizedTests { @Test public void getInstancesForServiceWorks() { - List instances = discoveryClient.getInstances("consul"); - assertNotNull("instances was null", instances); - assertFalse("instances was empty", instances.isEmpty()); + List instances = this.discoveryClient.getInstances("consul"); + assertThat(instances).as("instances was null").isNotNull(); + assertThat(instances.isEmpty()).as("instances was empty").isFalse(); } private void assertNotIpAddress(ServiceInstance instance) { - assertFalse("host is an ip address", - InetAddressUtils.isIPv4Address(instance.getHost())); + assertThat(InetAddressUtils.isIPv4Address(instance.getHost())) + .as("host is an ip address").isFalse(); } @Test public void getMetadataWorks() throws InterruptedException { - List instances = discoveryClient + List instances = this.discoveryClient .getInstances("testConsulDiscovery2"); - assertNotNull("instances was null", instances); - assertFalse("instances was empty", instances.isEmpty()); + assertThat(instances).as("instances was null").isNotNull(); + assertThat(instances.isEmpty()).as("instances was empty").isFalse(); ServiceInstance instance = instances.get(0); assertInstance(instance); } private void assertInstance(ServiceInstance instance) { - assertEquals("instance id was wrong", "testConsulDiscovery2Id", instance.getInstanceId()); - assertEquals("service id was wrong", "testConsulDiscovery2", instance.getServiceId()); + assertThat(instance.getInstanceId()).as("instance id was wrong") + .isEqualTo("testConsulDiscovery2Id"); + assertThat(instance.getServiceId()).as("service id was wrong") + .isEqualTo("testConsulDiscovery2"); Map metadata = instance.getMetadata(); - assertNotNull("metadata was null", metadata); + assertThat(metadata).as("metadata was null").isNotNull(); String foo = metadata.get("foo"); - assertEquals("metadata key foo was wrong", "bar", foo); + assertThat(foo).as("metadata key foo was wrong").isEqualTo("bar"); String plaintag = metadata.get("plaintag"); - assertEquals("metadata key plaintag was wrong", "plaintag", plaintag); + assertThat(plaintag).as("metadata key plaintag was wrong").isEqualTo("plaintag"); String foo2 = metadata.get("foo2"); - assertEquals("metadata key foo2 was wrong", "bar2=baz2", foo2); + assertThat(foo2).as("metadata key foo2 was wrong").isEqualTo("bar2=baz2"); } @Configuration @@ -98,4 +98,5 @@ public class ConsulDiscoveryClientCustomizedTests { public static class MyTestConfig { } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientDefaultQueryTagTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientDefaultQueryTagTests.java index c148c0b5..c760b7d5 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientDefaultQueryTagTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientDefaultQueryTagTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -19,38 +19,33 @@ package org.springframework.cloud.consul.discovery; import java.util.Arrays; import java.util.List; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.agent.model.NewService; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.agent.model.NewService; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasEntry; -import static org.hamcrest.Matchers.hasSize; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.MOCK; /** * @author Piotr Wielgolaski */ @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = MOCK, - classes = ConsulDiscoveryClientDefaultQueryTagTests.TestConfig.class, - properties = { - "spring.application.name=consulServiceDefaultTag", - "spring.cloud.consul.discovery.catalogServicesWatch.enabled=false", - "spring.cloud.consul.discovery.defaultQueryTag=intg"}) +@SpringBootTest(webEnvironment = MOCK, classes = ConsulDiscoveryClientDefaultQueryTagTests.TestConfig.class, properties = { + "spring.application.name=consulServiceDefaultTag", + "spring.cloud.consul.discovery.catalogServicesWatch.enabled=false", + "spring.cloud.consul.discovery.defaultQueryTag=intg" }) @DirtiesContext public class ConsulDiscoveryClientDefaultQueryTagTests { @@ -63,25 +58,27 @@ public class ConsulDiscoveryClientDefaultQueryTagTests { private ConsulClient consulClient; private NewService intgService = serviceForEnvironment("intg", 9081); + private NewService uatService = serviceForEnvironment("uat", 9080); @Before public void setUp() throws Exception { - consulClient.agentServiceRegister(intgService); - consulClient.agentServiceRegister(uatService); + this.consulClient.agentServiceRegister(this.intgService); + this.consulClient.agentServiceRegister(this.uatService); } @After public void tearDown() throws Exception { - consulClient.agentServiceDeregister(intgService.getId()); - consulClient.agentServiceDeregister(uatService.getId()); + this.consulClient.agentServiceDeregister(this.intgService.getId()); + this.consulClient.agentServiceDeregister(this.uatService.getId()); } @Test public void shouldReturnOnlyIntgInstance() { - List instances = discoveryClient.getInstances(NAME); - assertThat("instances was wrong size", instances, hasSize(1)); - assertThat("instance is not intg", instances.get(0).getMetadata(), hasEntry("intg", "intg")); + List instances = this.discoveryClient.getInstances(NAME); + assertThat(instances).as("instances was wrong size").hasSize(1); + assertThat(instances.get(0).getMetadata()).as("instance is not intg") + .containsEntry("intg", "intg"); } private NewService serviceForEnvironment(String env, int port) { @@ -100,4 +97,5 @@ public class ConsulDiscoveryClientDefaultQueryTagTests { protected static class TestConfig { } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientHttpsTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientHttpsTests.java index c653a6f0..0e88c18e 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientHttpsTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientHttpsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,11 @@ package org.springframework.cloud.consul.discovery; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -33,15 +29,16 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + /** * @author Glen Lockhart */ @RunWith(SpringRunner.class) @SpringBootTest(properties = { "spring.application.name=testConsulDiscoveryHttps", - "spring.cloud.consul.discovery.prefer-ip-address=true", - "spring.cloud.consul.discovery.scheme=https"}, - classes = ConsulDiscoveryClientHttpsTests.MyTestConfig.class, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.prefer-ip-address=true", + "spring.cloud.consul.discovery.scheme=https" }, classes = ConsulDiscoveryClientHttpsTests.MyTestConfig.class, webEnvironment = RANDOM_PORT) public class ConsulDiscoveryClientHttpsTests { @Autowired @@ -49,12 +46,13 @@ public class ConsulDiscoveryClientHttpsTests { @Test public void getInstancesForServiceWorks() { - List instances = discoveryClient.getInstances("testConsulDiscoveryHttps"); - assertNotNull("instances was null", instances); - assertFalse("instances was empty", instances.isEmpty()); + List instances = this.discoveryClient + .getInstances("testConsulDiscoveryHttps"); + assertThat(instances).as("instances was null").isNotNull(); + assertThat(instances.isEmpty()).as("instances was empty").isFalse(); ServiceInstance instance = instances.get(0); - assertTrue("instance was not secure (https)", instance.isSecure()); + assertThat(instance.isSecure()).as("instance was not secure (https)").isTrue(); } @Configuration @@ -63,4 +61,5 @@ public class ConsulDiscoveryClientHttpsTests { public static class MyTestConfig { } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientTests.java index c27ecad2..79caaeb4 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,14 @@ package org.springframework.cloud.consul.discovery; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - import java.util.List; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.QueryParams; +import com.ecwid.consul.v1.Response; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -34,9 +32,8 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.QueryParams; -import com.ecwid.consul.v1.Response; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Spencer Gibb @@ -45,46 +42,46 @@ import com.ecwid.consul.v1.Response; @RunWith(SpringRunner.class) @SpringBootTest(properties = { "spring.application.name=testConsulDiscovery", "spring.cloud.consul.discovery.prefer-ip-address=true", - "spring.cloud.consul.discovery.tags=foo=bar", }, - classes = ConsulDiscoveryClientTests.MyTestConfig.class, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.tags=foo=bar" }, classes = ConsulDiscoveryClientTests.MyTestConfig.class, webEnvironment = RANDOM_PORT) public class ConsulDiscoveryClientTests { @Autowired private ConsulDiscoveryClient discoveryClient; + @Autowired private ConsulClient consulClient; @Test public void getInstancesForServiceWorks() { - List instances = discoveryClient.getInstances("testConsulDiscovery"); - assertNotNull("instances was null", instances); - assertFalse("instances was empty", instances.isEmpty()); + List instances = this.discoveryClient + .getInstances("testConsulDiscovery"); + assertThat(instances).as("instances was null").isNotNull(); + assertThat(instances.isEmpty()).as("instances was empty").isFalse(); ServiceInstance instance = instances.get(0); - assertFalse("instance was secure (https)", instance.isSecure()); + assertThat(instance.isSecure()).as("instance was secure (https)").isFalse(); assertIpAddress(instance); - assertThat(instance.getMetadata()) - .containsEntry("foo", "bar"); + assertThat(instance.getMetadata()).containsEntry("foo", "bar"); } @Test public void getInstancesForServiceRespectsQueryParams() { - Response> catalogDatacenters = consulClient.getCatalogDatacenters(); + Response> catalogDatacenters = this.consulClient + .getCatalogDatacenters(); List dataCenterList = catalogDatacenters.getValue(); - assertFalse("no data centers found", dataCenterList.isEmpty()); - List instances = discoveryClient.getInstances("testConsulDiscovery", - new QueryParams(dataCenterList.get(0))); - assertFalse("instances was empty", instances.isEmpty()); + assertThat(dataCenterList.isEmpty()).as("no data centers found").isFalse(); + List instances = this.discoveryClient.getInstances( + "testConsulDiscovery", new QueryParams(dataCenterList.get(0))); + assertThat(instances.isEmpty()).as("instances was empty").isFalse(); ServiceInstance instance = instances.get(0); assertIpAddress(instance); } private void assertIpAddress(ServiceInstance instance) { - assertTrue("host isn't an ip address", - Character.isDigit(instance.getHost().charAt(0))); + assertThat(Character.isDigit(instance.getHost().charAt(0))) + .as("host isn't an ip address").isTrue(); } @Configuration @@ -93,4 +90,5 @@ public class ConsulDiscoveryClientTests { public static class MyTestConfig { } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryPropertiesTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryPropertiesTests.java index c863f272..609de5a0 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryPropertiesTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryPropertiesTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2019 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.consul.discovery; import java.util.Collections; @@ -10,59 +26,73 @@ import org.springframework.cloud.commons.util.InetUtils; import org.springframework.cloud.commons.util.InetUtilsProperties; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; public class ConsulDiscoveryPropertiesTests { private static final String DEFAULT_TAG = "defaultTag"; + private static final String MAP_TAG = "mapTag"; + private static final String MAP_DC = "mapDc"; + private static final String SERVICE_NAME_IN_MAP = "serviceNameInMap"; + private static final String SERVICE_NAME_NOT_IN_MAP = "serviceNameNotInMap"; + + private final Map serverListQueryTags = Collections + .singletonMap(SERVICE_NAME_IN_MAP, MAP_TAG); + + private final Map datacenters = Collections + .singletonMap(SERVICE_NAME_IN_MAP, MAP_DC); + private ConsulDiscoveryProperties properties; - private final Map serverListQueryTags = Collections.singletonMap(SERVICE_NAME_IN_MAP, MAP_TAG); - private final Map datacenters = Collections.singletonMap(SERVICE_NAME_IN_MAP, MAP_DC); @Before public void setUp() { - properties = new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties())); - properties.setDefaultQueryTag(DEFAULT_TAG); - properties.setServerListQueryTags(serverListQueryTags); - properties.setDatacenters(datacenters); + this.properties = new ConsulDiscoveryProperties( + new InetUtils(new InetUtilsProperties())); + this.properties.setDefaultQueryTag(DEFAULT_TAG); + this.properties.setServerListQueryTags(this.serverListQueryTags); + this.properties.setDatacenters(this.datacenters); } @Test public void testReturnsNullWhenNoDefaultAndNotInMap() { - properties.setDefaultQueryTag(null); + this.properties.setDefaultQueryTag(null); - assertNull(properties.getQueryTagForService(SERVICE_NAME_NOT_IN_MAP)); + assertThat(this.properties.getQueryTagForService(SERVICE_NAME_NOT_IN_MAP)) + .isNull(); } @Test public void testGetTagReturnsDefaultWhenNotInMap() { - assertEquals(DEFAULT_TAG, properties.getQueryTagForService(SERVICE_NAME_NOT_IN_MAP)); + assertThat(this.properties.getQueryTagForService(SERVICE_NAME_NOT_IN_MAP)) + .isEqualTo(DEFAULT_TAG); } @Test public void testGetTagReturnsMapValueWhenInMap() { - assertEquals(MAP_TAG, properties.getQueryTagForService(SERVICE_NAME_IN_MAP)); + assertThat(this.properties.getQueryTagForService(SERVICE_NAME_IN_MAP)) + .isEqualTo(MAP_TAG); } @Test public void testGetDcReturnsNullWhenNotInMap() { - assertNull(properties.getDatacenters().get(SERVICE_NAME_NOT_IN_MAP)); + assertThat(this.properties.getDatacenters().get(SERVICE_NAME_NOT_IN_MAP)) + .isNull(); } @Test public void testGetDcReturnsMapValueWhenInMap() { - assertEquals(MAP_DC, properties.getDatacenters().get(SERVICE_NAME_IN_MAP)); + assertThat(this.properties.getDatacenters().get(SERVICE_NAME_IN_MAP)) + .isEqualTo(MAP_DC); } @Test public void testAddManagementTag() { - properties.getManagementTags().add("newTag"); - assertThat(properties.getManagementTags()) + this.properties.getManagementTags().add("newTag"); + assertThat(this.properties.getManagementTags()) .containsOnly(ConsulDiscoveryProperties.MANAGEMENT, "newTag"); } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulLoadbalancerClientTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulLoadbalancerClientTests.java index d6867892..3960cf31 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulLoadbalancerClientTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulLoadbalancerClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -33,7 +33,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertTrue; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** @@ -42,8 +41,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @RunWith(SpringRunner.class) @SpringBootTest(properties = { "spring.application.name=testConsulLoadBalancer", "spring.cloud.consul.discovery.prefer-ip-address=true", - "spring.cloud.consul.discovery.tags=foo=bar", }, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.tags=foo=bar" }, webEnvironment = RANDOM_PORT) public class ConsulLoadbalancerClientTests { @Autowired @@ -51,25 +49,26 @@ public class ConsulLoadbalancerClientTests { @Test public void chooseWorks() { - ServiceInstance instance = client.choose("testConsulLoadBalancer"); + ServiceInstance instance = this.client.choose("testConsulLoadBalancer"); assertThat(instance).isNotNull(); assertThat(instance.isSecure()).isFalse(); assertIpAddress(instance); - assertThat(instance.getMetadata()) - .containsEntry("foo", "bar"); + assertThat(instance.getMetadata()).containsEntry("foo", "bar"); } private void assertIpAddress(ServiceInstance instance) { - assertTrue("host isn't an ip address", - Character.isDigit(instance.getHost().charAt(0))); + assertThat(Character.isDigit(instance.getHost().charAt(0))) + .as("host isn't an ip address").isTrue(); } @SpringBootConfiguration @EnableAutoConfiguration @EnableDiscoveryClient @RibbonClient(name = "testConsulLoadBalancer", configuration = MyRibbonConfig.class) - public static class MyTestConfig { } + public static class MyTestConfig { + + } public static class MyRibbonConfig { @@ -81,5 +80,7 @@ public class ConsulLoadbalancerClientTests { public ServerListFilter ribbonServerListFilter() { return servers -> servers; } + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerListAclTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerListAclTests.java index 6d6b4805..fd10c392 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerListAclTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerListAclTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,11 @@ package org.springframework.cloud.consul.discovery; import java.util.List; +import com.ecwid.consul.v1.ConsulClient; +import com.netflix.client.config.DefaultClientConfigImpl; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -27,45 +30,42 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.netflix.client.config.DefaultClientConfigImpl; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** - * @author bomee + * @author b omee */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulServerListAclTests.TestConfig.class, - properties = {"spring.application.name=testConsulServerListAcl", - "spring.cloud.consul.discovery.preferIpAddress=true", - "consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304"}, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = ConsulServerListAclTests.TestConfig.class, properties = { + "spring.application.name=testConsulServerListAcl", + "spring.cloud.consul.discovery.preferIpAddress=true", + "consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304" }, webEnvironment = RANDOM_PORT) public class ConsulServerListAclTests { - @Autowired - private ConsulClient consulClient; + @Autowired + private ConsulClient consulClient; - @Autowired - private ConsulDiscoveryProperties properties; + @Autowired + private ConsulDiscoveryProperties properties; - @Test - public void serverListWorksWithAcl() { - ConsulServerList consulServerList = new ConsulServerList(consulClient, properties); - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setClientName("testConsulServerListAcl"); - consulServerList.initWithNiwsConfig(config); - List servers = consulServerList.getUpdatedListOfServers(); - assertNotNull("servers was null", servers); - assertFalse("servers was empty", servers.isEmpty()); - } + @Test + public void serverListWorksWithAcl() { + ConsulServerList consulServerList = new ConsulServerList(this.consulClient, + this.properties); + DefaultClientConfigImpl config = new DefaultClientConfigImpl(); + config.setClientName("testConsulServerListAcl"); + consulServerList.initWithNiwsConfig(config); + List servers = consulServerList.getUpdatedListOfServers(); + assertThat(servers).as("servers was null").isNotNull(); + assertThat(servers.isEmpty()).as("servers was empty").isFalse(); + } - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - public static class TestConfig { + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + public static class TestConfig { + + } - } } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerListTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerListTests.java index 5e68d276..d158a86a 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerListTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerListTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,22 +20,21 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; -import org.junit.Test; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.commons.util.InetUtilsProperties; - import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.agent.model.NewService; import com.netflix.client.config.DefaultClientConfigImpl; +import org.junit.Test; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; +import org.springframework.cloud.commons.util.InetUtils; +import org.springframework.cloud.commons.util.InetUtilsProperties; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Spencer Gibb */ public class ConsulServerListTests { + private final String name = "consulServerListTestsService"; @Test @@ -48,10 +47,12 @@ public class ConsulServerListTests { NewService tagged = createService("Tagged", 9080, Arrays.asList(tag)); String zone = "myzone"; - NewService withZone = createService("WithZone", 10080, Arrays.asList("zone=" + zone)); + NewService withZone = createService("WithZone", 10080, + Arrays.asList("zone=" + zone)); String group = "test"; - NewService withGroup = createService("WithGroup", 11080, Arrays.asList("group=" + group)); + NewService withGroup = createService("WithGroup", 11080, + Arrays.asList("group=" + group)); try { consul.agentServiceRegister(nonTagged); @@ -61,43 +62,51 @@ public class ConsulServerListTests { InetUtils inetUtils = new InetUtils(new InetUtilsProperties()); DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setClientName(name); + config.setClientName(this.name); - ConsulServerList serverList = new ConsulServerList(consul, new ConsulDiscoveryProperties(inetUtils)); + ConsulServerList serverList = new ConsulServerList(consul, + new ConsulDiscoveryProperties(inetUtils)); serverList.initWithNiwsConfig(config); List servers = serverList.getInitialListOfServers(); - assertThat("servers was wrong size", servers, hasSize(4)); + assertThat(servers).as("servers was wrong size").hasSize(4); int serverWithZoneCount = 0; for (ConsulServer server : servers) { if (server.getMetadata().containsKey("zone")) { serverWithZoneCount++; - assertThat("server was wrong zone", server.getZone(), is(zone)); - } else { - assertThat("server was wrong zone", server.getZone(), is(ConsulServer.UNKNOWN_ZONE)); + assertThat(server.getZone()).as("server was wrong zone") + .isEqualTo(zone); + } + else { + assertThat(server.getZone()).as("server was wrong zone") + .isEqualTo(ConsulServer.UNKNOWN_ZONE); } } - assertThat("server was wrong zone", serverWithZoneCount, is(1)); + assertThat(serverWithZoneCount).as("server was wrong zone").isEqualTo(1); - serverList = new ConsulServerList(consul, getProperties(name, tag, inetUtils)); + serverList = new ConsulServerList(consul, + getProperties(this.name, tag, inetUtils)); serverList.initWithNiwsConfig(config); servers = serverList.getInitialListOfServers(); - assertThat("servers was wrong size", servers, hasSize(1)); + assertThat(servers).as("servers was wrong size").hasSize(1); ConsulServer server = servers.get(0); - assertThat("server was wrong", server.getPort(), is(9080)); + assertThat(server.getPort()).as("server was wrong").isEqualTo(9080); // test server group - serverList = new ConsulServerList(consul, getProperties(name, "group=" + group, inetUtils)); + serverList = new ConsulServerList(consul, + getProperties(this.name, "group=" + group, inetUtils)); serverList.initWithNiwsConfig(config); servers = serverList.getInitialListOfServers(); - assertThat("servers was wrong size", servers, hasSize(1)); + assertThat(servers).as("servers was wrong size").hasSize(1); server = servers.get(0); - assertThat("server was wrong", server.getPort(), is(11080)); - assertThat("server group was wrong", server.getMetaInfo().getServerGroup(), is(group)); - } finally { + assertThat(server.getPort()).as("server was wrong").isEqualTo(11080); + assertThat(server.getMetaInfo().getServerGroup()).as("server group was wrong") + .isEqualTo(group); + } + finally { consul.agentServiceDeregister(nonTagged.getId()); consul.agentServiceDeregister(tagged.getId()); consul.agentServiceDeregister(withZone.getId()); @@ -105,7 +114,8 @@ public class ConsulServerListTests { } } - private ConsulDiscoveryProperties getProperties(String name, String tag, InetUtils inetUtils) { + private ConsulDiscoveryProperties getProperties(String name, String tag, + InetUtils inetUtils) { ConsulDiscoveryProperties properties = new ConsulDiscoveryProperties(inetUtils); HashMap map = new HashMap<>(); map.put(name, tag); @@ -115,8 +125,8 @@ public class ConsulServerListTests { private NewService createService(String id, int port, List tags) { NewService service = new NewService(); - service.setName(name); - service.setId(name + id); + service.setName(this.name); + service.setId(this.name + id); service.setAddress("localhost"); service.setPort(port); if (tags != null) { @@ -124,4 +134,5 @@ public class ConsulServerListTests { } return service; } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerUtilsTest.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerUtilsTest.java index f34b8472..755f94a0 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerUtilsTest.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerUtilsTest.java @@ -1,8 +1,24 @@ +/* + * Copyright 2013-2019 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.consul.discovery; import org.junit.Test; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Semenkov Alexey @@ -12,19 +28,20 @@ public class ConsulServerUtilsTest { @Test public void testAddressFormat() { String s1 = ConsulServerUtils.fixIPv6Address("fc00:ec:cd::242:ac11:c"); - assertEquals("[fc00:ec:cd:0:0:242:ac11:c]", s1); + assertThat(s1).isEqualTo("[fc00:ec:cd:0:0:242:ac11:c]"); String s2 = ConsulServerUtils.fixIPv6Address("[fc00:ec:cd::242:ac11:c]"); - assertEquals("[fc00:ec:cd:0:0:242:ac11:c]", s2); + assertThat(s2).isEqualTo("[fc00:ec:cd:0:0:242:ac11:c]"); String s3 = ConsulServerUtils.fixIPv6Address("192.168.0.1"); - assertEquals("192.168.0.1", s3); + assertThat(s3).isEqualTo("192.168.0.1"); String s4 = ConsulServerUtils.fixIPv6Address("projects.spring.io"); - assertEquals("projects.spring.io", s4); + assertThat(s4).isEqualTo("projects.spring.io"); String s5 = ConsulServerUtils.fixIPv6Address("veryLongHostName"); - assertEquals("veryLongHostName", s5); + assertThat(s5).isEqualTo("veryLongHostName"); } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HealthServiceServerListFilterTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HealthServiceServerListFilterTests.java index dd3a7609..7162d694 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HealthServiceServerListFilterTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HealthServiceServerListFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -22,12 +22,12 @@ import java.util.List; import com.ecwid.consul.v1.health.model.Check; import com.ecwid.consul.v1.health.model.HealthService; import com.netflix.loadbalancer.Server; - import org.junit.Test; -import static com.ecwid.consul.v1.health.model.Check.CheckStatus.*; -import static org.junit.Assert.assertThat; -import static org.hamcrest.Matchers.*; +import static com.ecwid.consul.v1.health.model.Check.CheckStatus.CRITICAL; +import static com.ecwid.consul.v1.health.model.Check.CheckStatus.PASSING; +import static com.ecwid.consul.v1.health.model.Check.CheckStatus.WARNING; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Spencer Gibb @@ -45,20 +45,20 @@ public class HealthServiceServerListFilterTests { servers.add(newServer(WARNING)); List filtered = filter.getFilteredListOfServers(servers); - assertThat("wrong # of filtered servers", filtered, hasSize(2)); + assertThat(filtered).as("wrong # of filtered servers").hasSize(2); } private ConsulServer newServer(Check.CheckStatus checkStatus) { HealthService healthService = new HealthService(); HealthService.Node node = new HealthService.Node(); - node.setAddress("nodeaddr"+checkStatus.name()); - node.setNode("nodenode"+checkStatus.name()); + node.setAddress("nodeaddr" + checkStatus.name()); + node.setNode("nodenode" + checkStatus.name()); healthService.setNode(node); HealthService.Service service = new HealthService.Service(); - service.setAddress("serviceaddr"+checkStatus.name()); - service.setId("serviceid"+checkStatus.name()); + service.setAddress("serviceaddr" + checkStatus.name()); + service.setId("serviceid" + checkStatus.name()); service.setPort(8080); - service.setService("serviceservice"+checkStatus.name()); + service.setService("serviceservice" + checkStatus.name()); healthService.setService(service); ArrayList checks = new ArrayList<>(); Check check = new Check(); @@ -67,4 +67,5 @@ public class HealthServiceServerListFilterTests { healthService.setChecks(checks); return new ConsulServer(healthService); } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HeartbeatPropertiesTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HeartbeatPropertiesTests.java index bfdb5023..dcf7bacd 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HeartbeatPropertiesTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HeartbeatPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,35 +16,33 @@ package org.springframework.cloud.consul.discovery; -import static org.junit.Assert.assertThat; -import static org.hamcrest.Matchers.*; - import org.joda.time.Period; import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Spencer Gibb */ public class HeartbeatPropertiesTests { - @Test - public void computeHeartbeatIntervalWorks() { - HeartbeatProperties properties = new HeartbeatProperties(); - Period period = properties.computeHearbeatInterval(); + @Test + public void computeHeartbeatIntervalWorks() { + HeartbeatProperties properties = new HeartbeatProperties(); + Period period = properties.computeHearbeatInterval(); - assertThat(period, is(notNullValue())); - assertThat(period.getSeconds(), is(20)); - } + assertThat(period).isNotNull(); + assertThat(period.getSeconds()).isEqualTo(20); + } - @Test - public void computeShortHeartbeat() { - HeartbeatProperties properties = new HeartbeatProperties(); - properties.setTtlValue(2); - Period period = properties.computeHearbeatInterval(); - - assertThat(period, is(notNullValue())); - assertThat(period.getSeconds(), is(1)); - } + @Test + public void computeShortHeartbeat() { + HeartbeatProperties properties = new HeartbeatProperties(); + properties.setTtlValue(2); + Period period = properties.computeHearbeatInterval(); + assertThat(period).isNotNull(); + assertThat(period.getSeconds()).isEqualTo(1); + } } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/TtlSchedulerRemoveTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/TtlSchedulerRemoveTests.java index c796ebcd..37a2b361 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/TtlSchedulerRemoveTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/TtlSchedulerRemoveTests.java @@ -1,9 +1,30 @@ +/* + * Copyright 2013-2019 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.consul.discovery; import java.util.List; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.QueryParams; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.health.model.Check; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -13,27 +34,20 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.QueryParams; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.health.model.Check; - import static com.ecwid.consul.v1.health.model.Check.CheckStatus.CRITICAL; import static com.ecwid.consul.v1.health.model.Check.CheckStatus.PASSING; -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Stéphane Leroy */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = TtlSchedulerRemoveTests.TtlSchedulerRemoveTestConfig.class, - properties = { "spring.application.name=ttlSchedulerRemove", +@SpringBootTest(classes = TtlSchedulerRemoveTests.TtlSchedulerRemoveTestConfig.class, properties = { + "spring.application.name=ttlSchedulerRemove", "spring.cloud.consul.discovery.instance-id=ttlSchedulerRemove-id", "spring.cloud.consul.discovery.heartbeat.enabled=true", - "spring.cloud.consul.discovery.heartbeat.ttlValue=2" }, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.heartbeat.ttlValue=2" }, webEnvironment = RANDOM_PORT) public class TtlSchedulerRemoveTests { @Autowired @@ -46,20 +60,20 @@ public class TtlSchedulerRemoveTests { public void should_not_send_check_if_service_removed() throws InterruptedException { Thread.sleep(1000); // wait for Ttlscheduler to send a check to consul. Check serviceCheck = getCheckForService("ttlSchedulerRemove"); - assertThat("Service check is in wrong state", serviceCheck.getStatus(), - equalTo(PASSING)); + assertThat(serviceCheck.getStatus()).as("Service check is in wrong state") + .isEqualTo(PASSING); // Remove service from TtlScheduler and wait for TTL to expired. - ttlScheduler.remove("ttlSchedulerRemove-id"); + this.ttlScheduler.remove("ttlSchedulerRemove-id"); Thread.sleep(2100); serviceCheck = getCheckForService("ttlSchedulerRemove"); - assertThat("Service check is in wrong state", serviceCheck.getStatus(), - equalTo(CRITICAL)); + assertThat(serviceCheck.getStatus()).as("Service check is in wrong state") + .isEqualTo(CRITICAL); } private Check getCheckForService(String serviceId) { - Response> checkResponse = consul.getHealthChecksForService(serviceId, - QueryParams.DEFAULT); + Response> checkResponse = this.consul + .getHealthChecksForService(serviceId, QueryParams.DEFAULT); if (checkResponse.getValue().size() > 0) { return checkResponse.getValue().get(0); } @@ -68,9 +82,10 @@ public class TtlSchedulerRemoveTests { @Configuration @EnableAutoConfiguration - @Import({ AutoServiceRegistrationConfiguration.class, - ConsulAutoConfiguration.class, + @Import({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulDiscoveryClientConfiguration.class }) - public static class TtlSchedulerRemoveTestConfig { } -} + public static class TtlSchedulerRemoveTestConfig { + } + +} diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/TtlSchedulerTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/TtlSchedulerTests.java index 48f15a52..1a485343 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/TtlSchedulerTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/TtlSchedulerTests.java @@ -1,9 +1,30 @@ +/* + * Copyright 2013-2019 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.consul.discovery; import java.util.List; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.QueryParams; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.health.model.Check; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -13,11 +34,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.QueryParams; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.health.model.Check; - import static com.ecwid.consul.v1.health.model.Check.CheckStatus.PASSING; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @@ -26,12 +42,12 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author Stéphane Leroy */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = TtlSchedulerTests.TtlSchedulerTestConfig.class, - properties = { "spring.application.name=ttlScheduler", +@SpringBootTest(classes = TtlSchedulerTests.TtlSchedulerTestConfig.class, properties = { + "spring.application.name=ttlScheduler", "spring.cloud.consul.discovery.instance-id=ttlScheduler-id", "spring.cloud.consul.discovery.heartbeat.enabled=true", - "spring.cloud.consul.discovery.heartbeat.ttlValue=2", "management.server.port=0" }, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.heartbeat.ttlValue=2", + "management.server.port=0" }, webEnvironment = RANDOM_PORT) public class TtlSchedulerTests { @Autowired @@ -53,8 +69,8 @@ public class TtlSchedulerTests { } private Check getCheckForService(String serviceId) { - Response> checkResponse = consul.getHealthChecksForService(serviceId, - QueryParams.DEFAULT); + Response> checkResponse = this.consul + .getHealthChecksForService(serviceId, QueryParams.DEFAULT); if (checkResponse.getValue().size() > 0) { return checkResponse.getValue().get(0); } @@ -63,10 +79,10 @@ public class TtlSchedulerTests { @Configuration @EnableAutoConfiguration - @Import({ AutoServiceRegistrationConfiguration.class, - ConsulAutoConfiguration.class, + @Import({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulDiscoveryClientConfiguration.class }) - public static class TtlSchedulerTestConfig { } + public static class TtlSchedulerTestConfig { + + } + } - - diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfigurationTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfigurationTests.java index 25760a71..ada9ac66 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfigurationTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,6 +18,7 @@ package org.springframework.cloud.consul.discovery.configclient; import org.junit.After; import org.junit.Test; + import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -26,9 +27,7 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import static org.hamcrest.Matchers.contains; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Dave Syer @@ -48,25 +47,28 @@ public class ConsulConfigServerAutoConfigurationTests { public void offByDefault() throws Exception { this.context = new AnnotationConfigApplicationContext( ConsulConfigServerAutoConfiguration.class); - assertEquals(0, - this.context.getBeanNamesForType(ConsulDiscoveryProperties.class).length); + assertThat( + this.context.getBeanNamesForType(ConsulDiscoveryProperties.class).length) + .isEqualTo(0); } @Test public void onWhenRequested() throws Exception { setup("spring.cloud.config.server.prefix=/config"); - assertEquals(1, - this.context.getBeanNamesForType(ConsulDiscoveryProperties.class).length); - ConsulDiscoveryProperties properties = this.context.getBean(ConsulDiscoveryProperties.class); - assertThat(properties.getTags(), contains("configPath=/config")); + assertThat( + this.context.getBeanNamesForType(ConsulDiscoveryProperties.class).length) + .isEqualTo(1); + ConsulDiscoveryProperties properties = this.context + .getBean(ConsulDiscoveryProperties.class); + assertThat(properties.getTags()).containsExactly("configPath=/config"); } private void setup(String... env) { this.context = new SpringApplicationBuilder( PropertyPlaceholderAutoConfiguration.class, - ConsulConfigServerAutoConfiguration.class, - ConfigServerProperties.class, ConsulDiscoveryProperties.class).web(WebApplicationType.NONE) - .properties(env).run(); + ConsulConfigServerAutoConfiguration.class, ConfigServerProperties.class, + ConsulDiscoveryProperties.class).web(WebApplicationType.NONE) + .properties(env).run(); } } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/DiscoveryClientConfigServiceAutoConfigurationTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/DiscoveryClientConfigServiceAutoConfigurationTests.java index 58d75595..8e2eff06 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/DiscoveryClientConfigServiceAutoConfigurationTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/DiscoveryClientConfigServiceAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-2019 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. @@ -32,7 +32,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.AbstractApplicationContext; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; @@ -47,7 +47,7 @@ public class DiscoveryClientConfigServiceAutoConfigurationTests { @Before public void init() { - //FIXME: why do I need to do this? (fails in maven build without it. + // FIXME: why do I need to do this? (fails in maven build without it. TomcatURLStreamHandlerFactory.disable(); } @@ -67,29 +67,30 @@ public class DiscoveryClientConfigServiceAutoConfigurationTests { "logging.level.org.springframework.cloud.config.client=DEBUG", "spring.cloud.consul.discovery.test.enabled:true", "spring.application.name=discoveryclientconfigservicetest", - "spring.jmx.enabled=false", - "spring.cloud.consul.discovery.port:7001", + "spring.jmx.enabled=false", "spring.cloud.consul.discovery.port:7001", "spring.cloud.consul.discovery.hostname:foo", "spring.cloud.config.discovery.service-id:configserver"); - assertEquals( 1, this.context - .getBeanNamesForType(ConsulConfigServerAutoConfiguration.class).length); - ConsulDiscoveryClient client = this.context.getParent().getBean( - ConsulDiscoveryClient.class); + assertThat(this.context + .getBeanNamesForType(ConsulConfigServerAutoConfiguration.class).length) + .isEqualTo(1); + ConsulDiscoveryClient client = this.context.getParent() + .getBean(ConsulDiscoveryClient.class); verify(client, atLeast(2)).getInstances("configserver"); ConfigClientProperties locator = this.context .getBean(ConfigClientProperties.class); - assertEquals("http://foo:7001/", locator.getUri()[0]); + assertThat(locator.getUri()[0]).isEqualTo("http://foo:7001/"); } private void setup(String... env) { - this.context = new SpringApplicationBuilder(TestConfig.class) - .properties(env) + this.context = new SpringApplicationBuilder(TestConfig.class).properties(env) .run(); } @Configuration @EnableAutoConfiguration - protected static class TestConfig { } + protected static class TestConfig { + + } } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/TestConsulDiscoveryClientBootstrapConfiguration.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/TestConsulDiscoveryClientBootstrapConfiguration.java index 7b5540f1..c13a7d2b 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/TestConsulDiscoveryClientBootstrapConfiguration.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/TestConsulDiscoveryClientBootstrapConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2018 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.cloud.consul.discovery.configclient; +import java.util.Arrays; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; @@ -24,8 +26,6 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.Arrays; - import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; @@ -39,8 +39,8 @@ public class TestConsulDiscoveryClientBootstrapConfiguration { ConsulDiscoveryClient client = mock(ConsulDiscoveryClient.class); ServiceInstance instance = new DefaultServiceInstance("configserver", properties.getHostname(), properties.getPort(), false); - given(client.getInstances("configserver")) - .willReturn(Arrays.asList(instance)); + given(client.getInstances("configserver")).willReturn(Arrays.asList(instance)); return client; } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckHeadersTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckHeadersTests.java index 9ff390db..7de5e4a9 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckHeadersTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckHeadersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,10 @@ package org.springframework.cloud.consul.serviceregistry; -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - +import com.ecwid.consul.v1.agent.model.NewService; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -31,7 +30,8 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.agent.model.NewService; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Lomesh Patel @@ -69,5 +69,7 @@ public class ConsulAutoRegistrationHealthCheckHeadersTests { ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) public static class TestConfig { + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests.java index 7714d91e..fbe15e30 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 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. @@ -19,6 +19,7 @@ package org.springframework.cloud.consul.serviceregistry; import com.ecwid.consul.v1.agent.model.NewService; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -66,5 +67,7 @@ public class ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests { ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) public static class TestConfig { + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceDeRegistrationDisabledTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceDeRegistrationDisabledTests.java index bc86eecb..6e027a65 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceDeRegistrationDisabledTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceDeRegistrationDisabledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,14 @@ package org.springframework.cloud.consul.serviceregistry; +import java.util.Map; + import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.Response; import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -31,59 +34,62 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import java.util.Map; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Jon Freedman */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationDisabledTests.TestConfig.class, - properties = {"spring.application.name=myTestNotDeRegisteredService", - "spring.cloud.consul.discovery.instanceId=myTestNotDeRegisteredService-D", - "spring.cloud.consul.discovery.deregister=false"}, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = ConsulAutoServiceRegistrationDisabledTests.TestConfig.class, properties = { + "spring.application.name=myTestNotDeRegisteredService", + "spring.cloud.consul.discovery.instanceId=myTestNotDeRegisteredService-D", + "spring.cloud.consul.discovery.deregister=false" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceDeRegistrationDisabledTests { - @Autowired - private ConsulClient consul; - @Autowired(required = false) - private ConsulAutoServiceRegistration autoServiceRegistration; + @Autowired + private ConsulClient consul; - @Autowired(required = false) - private ConsulDiscoveryProperties discoveryProperties; + @Autowired(required = false) + private ConsulAutoServiceRegistration autoServiceRegistration; - @Test - public void contextLoads() { - assertNotNull("ConsulAutoServiceRegistration was not created", autoServiceRegistration); - assertNotNull("ConsulDiscoveryProperties was not created", discoveryProperties); + @Autowired(required = false) + private ConsulDiscoveryProperties discoveryProperties; - checkService(true); - autoServiceRegistration.deregister(); - checkService(true); - discoveryProperties.setDeregister(true); - autoServiceRegistration.deregister(); - checkService(false); - } + @Test + public void contextLoads() { + assertThat(this.autoServiceRegistration) + .as("ConsulAutoServiceRegistration was not created").isNotNull(); + assertThat(this.discoveryProperties) + .as("ConsulDiscoveryProperties was not created").isNotNull(); - private void checkService(final boolean expected) { - final Response> response = consul.getAgentServices(); - final Map services = response.getValue(); - final Service service = services.get("myTestNotDeRegisteredService-D"); - if (expected) { - assertNotNull("service was not registered", service); - } else { - assertNull("service was registered", service); - } - } + checkService(true); + this.autoServiceRegistration.deregister(); + checkService(true); + this.discoveryProperties.setDeregister(true); + this.autoServiceRegistration.deregister(); + checkService(false); + } + + private void checkService(final boolean expected) { + final Response> response = this.consul.getAgentServices(); + final Map services = response.getValue(); + final Service service = services.get("myTestNotDeRegisteredService-D"); + if (expected) { + assertThat(service).as("service was not registered").isNotNull(); + } + else { + assertThat(service).as("service was registered").isNull(); + } + } + + @Configuration + @EnableAutoConfiguration + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + public static class TestConfig { + + } - @Configuration - @EnableAutoConfiguration - @ImportAutoConfiguration({AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, - ConsulAutoServiceRegistrationAutoConfiguration.class}) - public static class TestConfig { - } } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedAgentAddressTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedAgentAddressTests.java index bd2ab02f..61716e30 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedAgentAddressTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedAgentAddressTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -30,45 +34,45 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.StringUtils; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedAgentAddressTests.TestConfig.class, - properties = { "spring.application.name=myTestService-AA", +@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedAgentAddressTests.TestConfig.class, properties = { + "spring.application.name=myTestService-AA", "spring.cloud.consul.discovery.instanceId=myTestService1-AA", "spring.cloud.consul.discovery.serviceName=myprefix-${spring.application.name}", - "spring.cloud.consul.discovery.preferAgentAddress=true"}, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.preferAgentAddress=true" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationCustomizedAgentAddressTests { @Autowired private ConsulClient consul; - + @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("myTestService1-AA"); - assertNotNull("service was null", service); - assertNotEquals("service port is 0", 0, service.getPort().intValue()); - assertEquals("service id was wrong", "myTestService1-AA", service.getId()); - assertEquals("service name was wrong", "myprefix-myTestService-AA", service.getService()); - assertTrue("service address must be empty", StringUtils.isEmpty(service.getAddress())); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo("myTestService1-AA"); + assertThat(service.getService()).as("service name was wrong") + .isEqualTo("myprefix-myTestService-AA"); + assertThat(StringUtils.isEmpty(service.getAddress())) + .as("service address must be empty").isTrue(); } @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - public static class TestConfig { } + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + public static class TestConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedDiscoveryPortTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedDiscoveryPortTests.java index ede0a2d3..c3798573 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedDiscoveryPortTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedDiscoveryPortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,12 @@ package org.springframework.cloud.consul.serviceregistry; +import com.ecwid.consul.v1.agent.model.NewService; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -31,8 +33,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.SocketUtils; -import com.ecwid.consul.v1.agent.model.NewService; - import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; @@ -40,9 +40,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedDiscoveryPortTests.TestConfig.class, - properties = { "spring.application.name=myTestService-DiscoveryPort", }, - webEnvironment = DEFINED_PORT) +@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedDiscoveryPortTests.TestConfig.class, properties = { + "spring.application.name=myTestService-DiscoveryPort" }, webEnvironment = DEFINED_PORT) public class ConsulAutoServiceRegistrationCustomizedDiscoveryPortTests { @Autowired @@ -73,17 +72,21 @@ public class ConsulAutoServiceRegistrationCustomizedDiscoveryPortTests { NewService.Check check = service.getCheck(); assertThat(check).as("check was null").isNotNull(); - String httpCheck = String.format("%s://%s:%s%s", properties.getScheme(), - properties.getHostname(), properties.getPort(), - properties.getHealthCheckPath()); + String httpCheck = String.format("%s://%s:%s%s", this.properties.getScheme(), + this.properties.getHostname(), this.properties.getPort(), + this.properties.getHealthCheckPath()); assertThat(check.getHttp()).as("http check was wrong").isEqualTo(httpCheck); // unable to call consul api to get health check details } - @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - public static class TestConfig { } + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + public static class TestConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedInstanceGroupTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedInstanceGroupTests.java index d2906a49..5063390d 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedInstanceGroupTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedInstanceGroupTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -19,8 +19,13 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.List; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; +import com.netflix.client.config.DefaultClientConfigImpl; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -33,26 +38,17 @@ import org.springframework.cloud.consul.discovery.ConsulServerList; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; -import com.netflix.client.config.DefaultClientConfigImpl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Jin Zhang */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedInstanceGroupTests.TestConfig.class, - properties = { "spring.application.name=myTestService-WithGroup", +@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedInstanceGroupTests.TestConfig.class, properties = { + "spring.application.name=myTestService-WithGroup", "spring.cloud.consul.discovery.instanceId=myTestService1-WithGroup", - "spring.cloud.consul.discovery.instanceGroup=test"}, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.instanceGroup=test" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationCustomizedInstanceGroupTests { @Autowired @@ -63,27 +59,34 @@ public class ConsulAutoServiceRegistrationCustomizedInstanceGroupTests { @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("myTestService1-WithGroup"); - assertNotNull("service was null", service); - assertNotEquals("service port is 0", 0, service.getPort().intValue()); - assertEquals("service id was wrong", "myTestService1-WithGroup", service.getId()); - assertTrue("service group was wrong", service.getTags().contains("group=test")); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo("myTestService1-WithGroup"); + assertThat(service.getTags().contains("group=test")).as("service group was wrong") + .isTrue(); - ConsulServerList serverList = new ConsulServerList(consul, properties); + ConsulServerList serverList = new ConsulServerList(this.consul, this.properties); DefaultClientConfigImpl config = new DefaultClientConfigImpl(); config.setClientName("myTestService-WithGroup"); serverList.initWithNiwsConfig(config); List servers = serverList.getInitialListOfServers(); - assertEquals("servers was wrong size", 1, servers.size()); - assertEquals("service group was wrong", "test", servers.get(0).getMetaInfo().getServerGroup()); + assertThat(servers.size()).as("servers was wrong size").isEqualTo(1); + assertThat(servers.get(0).getMetaInfo().getServerGroup()) + .as("service group was wrong").isEqualTo("test"); } - @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - public static class TestConfig { } + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + public static class TestConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedInstanceZoneTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedInstanceZoneTests.java index b02b0974..c7366769 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedInstanceZoneTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedInstanceZoneTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -29,26 +33,18 @@ import org.springframework.cloud.consul.ConsulAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Sixian Liu */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedInstanceZoneTests.TestConfig.class, - properties = { "spring.application.name=myTestService-WithZone", +@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedInstanceZoneTests.TestConfig.class, properties = { + "spring.application.name=myTestService-WithZone", "spring.cloud.consul.discovery.instanceId=myTestService1-WithZone", "spring.cloud.consul.discovery.instanceZone=zone1", - "spring.cloud.consul.discovery.defaultZoneMetadataName=myZone"}, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.defaultZoneMetadataName=myZone" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationCustomizedInstanceZoneTests { @Autowired @@ -56,17 +52,24 @@ public class ConsulAutoServiceRegistrationCustomizedInstanceZoneTests { @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("myTestService1-WithZone"); - assertNotNull("service was null", service); - assertNotEquals("service port is 0", 0, service.getPort().intValue()); - assertEquals("service id was wrong", "myTestService1-WithZone", service.getId()); - assertTrue("service zone was wrong", service.getTags().contains("myZone=zone1")); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo("myTestService1-WithZone"); + assertThat(service.getTags().contains("myZone=zone1")) + .as("service zone was wrong").isTrue(); } @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - public static class TestConfig { } + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + public static class TestConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedManagementServicePortTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedManagementServicePortTests.java index ef650a3f..f0ea3c93 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedManagementServicePortTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedManagementServicePortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,14 @@ package org.springframework.cloud.consul.serviceregistry; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertFalse; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -38,9 +36,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.StringUtils; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Aleksandr Tarasov (aatarasov) @@ -68,35 +65,37 @@ public class ConsulAutoServiceRegistrationCustomizedManagementServicePortTests { @Test public void contextLoads() { - final Response> response = consul.getAgentServices(); + final Response> response = this.consul.getAgentServices(); final Map services = response.getValue(); final Service service = services.get("myTestService1-GG"); - assertNotNull("service was null", service); - assertNotEquals("service port was 0", 0, service.getPort().intValue()); - assertEquals("service id was wrong", "myTestService1-GG", service.getId()); - assertEquals("service name was wrong", "myprefix-myTestService-GG", - service.getService()); - assertFalse("service address must not be empty", - StringUtils.isEmpty(service.getAddress())); - assertEquals("service address must equals hostname from discovery properties", - discoveryProperties.getHostname(), service.getAddress()); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port was 0").isNotEqualTo(0); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo("myTestService1-GG"); + assertThat(service.getService()).as("service name was wrong") + .isEqualTo("myprefix-myTestService-GG"); + assertThat(StringUtils.isEmpty(service.getAddress())) + .as("service address must not be empty").isFalse(); + assertThat(service.getAddress()) + .as("service address must equals hostname from discovery properties") + .isEqualTo(this.discoveryProperties.getHostname()); final Service managementService = services.get("myTestService1-GG-management"); - assertNotNull("management service was null", managementService); - assertEquals("management service port is not 4452", 4452, - managementService.getPort().intValue()); - assertEquals("management port is not 0", 0, - managementServerProperties.getPort().intValue()); - assertEquals("management service id was wrong", "myTestService1-GG-management", - managementService.getId()); - assertEquals("management service name was wrong", - "myprefix-myTestService-GG-management", managementService.getService()); - assertFalse("management service address must not be empty", - StringUtils.isEmpty(managementService.getAddress())); - assertEquals( - "management service address must equals hostname from discovery properties", - discoveryProperties.getHostname(), managementService.getAddress()); + assertThat(managementService).as("management service was null").isNotNull(); + assertThat(managementService.getPort().intValue()) + .as("management service port is not 4452").isEqualTo(4452); + assertThat(this.managementServerProperties.getPort().intValue()) + .as("management port is not 0").isEqualTo(0); + assertThat(managementService.getId()).as("management service id was wrong") + .isEqualTo("myTestService1-GG-management"); + assertThat(managementService.getService()).as("management service name was wrong") + .isEqualTo("myprefix-myTestService-GG-management"); + assertThat(StringUtils.isEmpty(managementService.getAddress())) + .as("management service address must not be empty").isFalse(); + assertThat(managementService.getAddress()).as( + "management service address must equals hostname from discovery properties") + .isEqualTo(this.discoveryProperties.getHostname()); } @Configuration @@ -105,5 +104,7 @@ public class ConsulAutoServiceRegistrationCustomizedManagementServicePortTests { ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) public static class TestConfig { + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedPropsTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedPropsTests.java index 38a0dc7e..24043a32 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedPropsTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedPropsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -19,8 +19,14 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.List; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.QueryParams; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; +import com.ecwid.consul.v1.health.model.Check; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -31,18 +37,7 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.QueryParams; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; -import com.ecwid.consul.v1.health.model.Check; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** @@ -50,15 +45,14 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author Venil Noronha */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedPropsTests.TestPropsConfig.class, - properties = { "spring.application.name=myTestService-B", +@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedPropsTests.TestPropsConfig.class, properties = { + "spring.application.name=myTestService-B", "spring.cloud.consul.discovery.instanceId=myTestService1-B", "spring.cloud.consul.discovery.port=4452", "spring.cloud.consul.discovery.hostname=myhost", "spring.cloud.consul.discovery.ipAddress=10.0.0.1", "spring.cloud.consul.discovery.registerHealthCheck=false", - "spring.cloud.consul.discovery.failFast=false" }, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.failFast=false" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationCustomizedPropsTests { @Autowired @@ -69,30 +63,42 @@ public class ConsulAutoServiceRegistrationCustomizedPropsTests { @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("myTestService1-B"); - assertThat("service was null", service, is(notNullValue())); - assertThat("service port is discovery port", service.getPort(), equalTo(4452)); - assertThat("service id was wrong", "myTestService1-B", equalTo(service.getId())); - assertThat("service name was wrong", "myTestService-B", equalTo(service.getService())); - assertThat("property hostname was wrong", "myhost", equalTo(this.properties.getHostname())); - assertThat("property ipAddress was wrong", "10.0.0.1", equalTo(this.properties.getIpAddress())); - assertThat("service address was wrong", "myhost", equalTo(service.getAddress())); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort()).as("service port is discovery port") + .isEqualTo(4452); + assertThat("myTestService1-B").as("service id was wrong") + .isEqualTo(service.getId()); + assertThat("myTestService-B").as("service name was wrong") + .isEqualTo(service.getService()); + assertThat("myhost").as("property hostname was wrong") + .isEqualTo(this.properties.getHostname()); + assertThat("10.0.0.1").as("property ipAddress was wrong") + .isEqualTo(this.properties.getIpAddress()); + assertThat("myhost").as("service address was wrong") + .isEqualTo(service.getAddress()); - Response> checkResponse = consul.getHealthChecksForService("myTestService-B", QueryParams.DEFAULT); + Response> checkResponse = this.consul + .getHealthChecksForService("myTestService-B", QueryParams.DEFAULT); List checks = checkResponse.getValue(); - assertThat("checks was wrong size", checks, hasSize(0)); + assertThat(checks).as("checks was wrong size").hasSize(0); } @Test public void testFailFastDisabled() { - assertFalse("property failFast was wrong", this.properties.isFailFast()); + assertThat(this.properties.isFailFast()).as("property failFast was wrong") + .isFalse(); } - @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - public static class TestPropsConfig { } + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + public static class TestPropsConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServiceNameTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServiceNameTests.java index f811467b..00e8bc7a 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServiceNameTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServiceNameTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -29,24 +33,17 @@ import org.springframework.cloud.consul.ConsulAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedServiceNameTests.TestConfig.class, - properties = { "spring.application.name=myTestService-CC", +@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedServiceNameTests.TestConfig.class, properties = { + "spring.application.name=myTestService-CC", "spring.cloud.consul.discovery.instanceId=myTestService1-CC", - "spring.cloud.consul.discovery.serviceName=myprefix-${spring.application.name}"}, - webEnvironment = RANDOM_PORT) + "spring.cloud.consul.discovery.serviceName=myprefix-${spring.application.name}" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationCustomizedServiceNameTests { @Autowired @@ -54,17 +51,24 @@ public class ConsulAutoServiceRegistrationCustomizedServiceNameTests { @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("myTestService1-CC"); - assertNotNull("service was null", service); - assertNotEquals("service port is 0", 0, service.getPort().intValue()); - assertEquals("service id was wrong", "myTestService1-CC", service.getId()); - assertEquals("service name was wrong", "myprefix-myTestService-CC", service.getService()); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo("myTestService1-CC"); + assertThat(service.getService()).as("service name was wrong") + .isEqualTo("myprefix-myTestService-CC"); } @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - public static class TestConfig { } + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + public static class TestConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServletContextTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServletContextTests.java index 0240e01f..64b1fcd0 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServletContextTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServletContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -27,10 +31,6 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @@ -38,11 +38,10 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author Piotr Wielgolaski */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedServletContextTests.TestConfig.class, - properties = { "spring.application.name=myTestService-WithServletContext", - "spring.cloud.consul.discovery.instanceId=myTestService1-WithServletContext", - "server.servlet.context-path=/customContext"}, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedServletContextTests.TestConfig.class, properties = { + "spring.application.name=myTestService-WithServletContext", + "spring.cloud.consul.discovery.instanceId=myTestService1-WithServletContext", + "server.servlet.context-path=/customContext" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationCustomizedServletContextTests { @Autowired @@ -50,17 +49,22 @@ public class ConsulAutoServiceRegistrationCustomizedServletContextTests { @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("myTestService1-WithServletContext"); assertThat(service).as("service was null").isNotNull(); assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); - assertThat(service.getId()).as("service id was wrong").isEqualTo("myTestService1-WithServletContext"); - assertThat(service.getTags()).as("contextPath tag missing").contains("contextPath=/customContext"); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo("myTestService1-WithServletContext"); + assertThat(service.getTags()).as("contextPath tag missing") + .contains("contextPath=/customContext"); } @EnableDiscoveryClient @Configuration @EnableAutoConfiguration - public static class TestConfig { } + public static class TestConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedTests.java index bc5115a1..397ac8d6 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,6 +18,7 @@ package org.springframework.cloud.consul.serviceregistry; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -30,16 +31,15 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.context.annotation.Bean; import org.springframework.test.context.junit4.SpringRunner; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Marcin Biegan */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedTests.MyTestConfig.class, - properties = { "spring.application.name=testCustomAutoServiceRegistration"}, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedTests.MyTestConfig.class, properties = { + "spring.application.name=testCustomAutoServiceRegistration" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationCustomizedTests { @Autowired @@ -53,14 +53,19 @@ public class ConsulAutoServiceRegistrationCustomizedTests { @Test public void usesCustomConsulLifecycle() { - assertEquals("configuration is not customized", "customconfiguration", registration1.getConfiguration()); - assertEquals("configuration is not customized", "customconfiguration", registration2.getConfiguration()); + assertThat(this.registration1.getConfiguration()) + .as("configuration is not customized").isEqualTo("customconfiguration"); + assertThat(this.registration2.getConfiguration()) + .as("configuration is not customized").isEqualTo("customconfiguration"); } @SpringBootConfiguration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) public static class MyTestConfig { + @Bean public CustomAutoRegistration consulAutoServiceRegistration( ConsulServiceRegistry serviceRegistry, @@ -70,6 +75,7 @@ public class ConsulAutoServiceRegistrationCustomizedTests { return new CustomAutoRegistration(serviceRegistry, autoServiceRegistrationProperties, properties, registration); } + } public static class CustomAutoRegistration extends ConsulAutoServiceRegistration { @@ -87,5 +93,7 @@ public class ConsulAutoServiceRegistrationCustomizedTests { protected Object getConfiguration() { return "customconfiguration"; } + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultCheckTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultCheckTests.java index 7abc02c4..b9b9b80e 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultCheckTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultCheckTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,16 @@ package org.springframework.cloud.consul.serviceregistry; +import com.ecwid.consul.v1.ConsulClient; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationCustomizedPropsTests.TestPropsConfig; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; - import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @@ -34,13 +34,12 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @deprecated remove in Edgware */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = TestPropsConfig.class, - properties = { "spring.application.name=myTestServiceDefaultChecks", - "spring.cloud.consul.discovery.instanceId=myTestServiceDefaultChecks", - "spring.cloud.consul.discovery.healthCheckCriticalTimeout=30m", - "spring.cloud.consul.discovery.healthCheckInterval=19s", - "spring.cloud.consul.discovery.healthCheckTimeout=12s", - }, webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = TestPropsConfig.class, properties = { + "spring.application.name=myTestServiceDefaultChecks", + "spring.cloud.consul.discovery.instanceId=myTestServiceDefaultChecks", + "spring.cloud.consul.discovery.healthCheckCriticalTimeout=30m", + "spring.cloud.consul.discovery.healthCheckInterval=19s", + "spring.cloud.consul.discovery.healthCheckTimeout=12s" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationDefaultCheckTests { @Autowired @@ -51,19 +50,25 @@ public class ConsulAutoServiceRegistrationDefaultCheckTests { @Test public void contextLoads() { - assertThat(properties.getHealthCheckCriticalTimeout()).isEqualTo("30m"); - assertThat(properties.getHealthCheckInterval()).isEqualTo("19s"); - assertThat(properties.getHealthCheckTimeout()).isEqualTo("12s"); + assertThat(this.properties.getHealthCheckCriticalTimeout()).isEqualTo("30m"); + assertThat(this.properties.getHealthCheckInterval()).isEqualTo("19s"); + assertThat(this.properties.getHealthCheckTimeout()).isEqualTo("12s"); - // I'm unable to find a way to query consul to see the configuration of the health check - // so for now, just sending the new healthCheckCriticalTimeout and having consul accept + // I'm unable to find a way to query consul to see the configuration of the health + // check + // so for now, just sending the new healthCheckCriticalTimeout and having consul + // accept // it is going to have to suffice - //final Response> checksForService = consul.getHealthChecksForService("myTestServiceDefaultChecks", QueryParams.DEFAULT); - //final List checkList = checksForService.getValue(); - //final Response> response2 = consul.getAgentChecks(); - //final Map checks = response2.getValue(); - //final Check check = checks.get("myTestServiceDefaultChecks"); - //Assertions.assertThat(check).isNotNull(); + // final Response> checksForService = + // consul.getHealthChecksForService("myTestServiceDefaultChecks", + // QueryParams.DEFAULT); + // final List checkList = + // checksForService.getValue(); + // final Response> response2 = consul.getAgentChecks(); + // final Map checks = response2.getValue(); + // final Check check = checks.get("myTestServiceDefaultChecks"); + // Assertions.assertThat(check).isNotNull(); } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultPortTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultPortTests.java index 40c84584..4c03c4ae 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultPortTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultPortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -29,22 +33,16 @@ import org.springframework.cloud.consul.ConsulAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationDefaultPortTests.TestConfig.class, - properties = { "spring.application.name=myTestService2-DD", - "spring.cloud.consul.discovery.instanceId=myTestService2-DD", }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = ConsulAutoServiceRegistrationDefaultPortTests.TestConfig.class, properties = { + "spring.application.name=myTestService2-DD", + "spring.cloud.consul.discovery.instanceId=myTestService2-DD" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationDefaultPortTests { @Autowired @@ -52,16 +50,20 @@ public class ConsulAutoServiceRegistrationDefaultPortTests { @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("myTestService2-DD"); - assertNotNull("service was null", service); - assertNotEquals("service port is 0", 0, service.getPort().intValue()); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); } @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - public static class TestConfig { } -} + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + public static class TestConfig { + } + +} diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDisabledTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDisabledTests.java index 6f873cf8..daa65415 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDisabledTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDisabledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -29,21 +33,16 @@ import org.springframework.cloud.consul.ConsulAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - -import static org.junit.Assert.assertNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationDisabledTests.TestConfig.class, - properties = { "spring.application.name=myTestNotRegisteredService2", - "spring.cloud.service-registry.auto-registration.enabled=false"}, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = ConsulAutoServiceRegistrationDisabledTests.TestConfig.class, properties = { + "spring.application.name=myTestNotRegisteredService2", + "spring.cloud.service-registry.auto-registration.enabled=false" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationDisabledTests { @Autowired @@ -54,17 +53,22 @@ public class ConsulAutoServiceRegistrationDisabledTests { @Test public void contextLoads() { - assertNull("ConsulAutoServiceRegistration was created", autoServiceRegistration); + assertThat(this.autoServiceRegistration) + .as("ConsulAutoServiceRegistration was created").isNull(); - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("myTestNotRegisteredService2"); - assertNull("service was registered", service); + assertThat(service).as("service was registered").isNull(); } @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - public static class TestConfig { } + public static class TestConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationFailFastTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationFailFastTests.java index d91e1f5e..b46c645d 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationFailFastTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationFailFastTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,12 @@ package org.springframework.cloud.consul.serviceregistry; +import com.ecwid.consul.ConsulException; +import com.ecwid.consul.v1.ConsulClient; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -28,9 +31,6 @@ import org.springframework.cloud.consul.ConsulAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.test.annotation.DirtiesContext; -import com.ecwid.consul.ConsulException; -import com.ecwid.consul.v1.ConsulClient; - /** * @author Spencer Gibb * @author Venil Noronha @@ -44,20 +44,25 @@ public class ConsulAutoServiceRegistrationFailFastTests { @Test public void testFailFastEnabled() { this.exception.expect(ConsulException.class); - new SpringApplicationBuilder(TestConfig.class).properties("spring.application.name=testregistrationfails-fast", - "spring.jmx.default-domain=testautoregfailfast", - "server.port=0", "spring.cloud.consul.discovery.failFast=true").run(); + new SpringApplicationBuilder(TestConfig.class) + .properties("spring.application.name=testregistrationfails-fast", + "spring.jmx.default-domain=testautoregfailfast", "server.port=0", + "spring.cloud.consul.discovery.failFast=true") + .run(); } @SpringBootConfiguration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) protected static class TestConfig { @Bean public ConsulClient consulClient() { return new ConsulClient("localhost", 4321); } - } -} + } + +} diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementCustomizerTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementCustomizerTests.java index ec60e25e..f8f46331 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementCustomizerTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementCustomizerTests.java @@ -16,10 +16,14 @@ package org.springframework.cloud.consul.serviceregistry; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import com.ecwid.consul.v1.agent.model.NewService; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -30,10 +34,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** @@ -42,12 +43,10 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @RunWith(SpringRunner.class) @SpringBootTest(classes = { ConsulAutoServiceRegistrationManagementCustomizerTests.TestConfig.class, - ConsulAutoServiceRegistrationManagementCustomizerTests.ManagementConfig.class -}, properties = { - "spring.application.name=myTestService-SS", - "spring.cloud.consul.discovery.registerHealthCheck=false", - "management.server.port=4453" -}, webEnvironment = RANDOM_PORT) + ConsulAutoServiceRegistrationManagementCustomizerTests.ManagementConfig.class }, properties = { + "spring.application.name=myTestService-SS", + "spring.cloud.consul.discovery.registerHealthCheck=false", + "management.server.port=4453" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationManagementCustomizerTests { @Autowired @@ -58,11 +57,17 @@ public class ConsulAutoServiceRegistrationManagementCustomizerTests { @Test public void contextLoads() { - ConsulAutoRegistration managementRegistration = autoRegistration.managementRegistration(); + ConsulAutoRegistration managementRegistration = this.autoRegistration + .managementRegistration(); List checks = managementRegistration.getService().getChecks(); - List ttls = checks.stream().map(NewService.Check::getTtl).collect(Collectors.toList()); - Assert.assertTrue("Management registration not customized with 'foo' customizer", ttls.contains("39s")); - Assert.assertTrue("Management registration not customized with 'bar' customizer", ttls.contains("36s")); + List ttls = checks.stream().map(NewService.Check::getTtl) + .collect(Collectors.toList()); + assertThat(ttls.contains("39s")) + .as("Management registration not customized with 'foo' customizer") + .isTrue(); + assertThat(ttls.contains("36s")) + .as("Management registration not customized with 'bar' customizer") + .isTrue(); } @Configuration @@ -86,7 +91,8 @@ public class ConsulAutoServiceRegistrationManagementCustomizerTests { NewService managementService = managementRegistration.getService(); NewService.Check check = new NewService.Check(); check.setTtl(ttl); - List checks = managementService.getChecks() != null ? new ArrayList<>(managementService.getChecks()) : new ArrayList<>(); + List checks = managementService.getChecks() != null + ? new ArrayList<>(managementService.getChecks()) : new ArrayList<>(); checks.add(check); managementRegistration.getService().setChecks(checks); } @@ -95,11 +101,11 @@ public class ConsulAutoServiceRegistrationManagementCustomizerTests { @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({ - AutoServiceRegistrationConfiguration.class, + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, - ConsulAutoServiceRegistrationAutoConfiguration.class - }) + ConsulAutoServiceRegistrationAutoConfiguration.class }) public static class TestConfig { + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementDisabledServiceTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementDisabledServiceTests.java index 029e5025..c51647d3 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementDisabledServiceTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementDisabledServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -31,15 +35,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.StringUtils; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** @@ -62,21 +58,24 @@ public class ConsulAutoServiceRegistrationManagementDisabledServiceTests { @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service mgmtService = services.get("myTestService-NM-0-management"); - assertNull("Management service was not null", mgmtService); + assertThat(mgmtService).as("Management service was not null").isNull(); Service service = services.get("myTestService1-NM"); - assertNotNull("Service was not null", service); - assertNotEquals("service port was 0", 0, service.getPort().intValue()); - assertEquals("service id was wrong", "myTestService1-NM", service.getId()); - assertEquals("service name was wrong", "myTestService-NM", service.getService()); - assertFalse("service address must not be empty", - StringUtils.isEmpty(service.getAddress())); - assertEquals("service address must equals hostname from discovery properties", - discoveryProperties.getHostname(), service.getAddress()); + assertThat(service).as("Service was not null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port was 0").isNotEqualTo(0); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo("myTestService1-NM"); + assertThat(service.getService()).as("service name was wrong") + .isEqualTo("myTestService-NM"); + assertThat(StringUtils.isEmpty(service.getAddress())) + .as("service address must not be empty").isFalse(); + assertThat(service.getAddress()) + .as("service address must equals hostname from discovery properties") + .isEqualTo(this.discoveryProperties.getHostname()); } @@ -86,5 +85,7 @@ public class ConsulAutoServiceRegistrationManagementDisabledServiceTests { ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) public static class TestConfig { + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementServiceTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementServiceTests.java index ab3a7c43..52250cd2 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementServiceTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationManagementServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,14 @@ package org.springframework.cloud.consul.serviceregistry; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertFalse; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -37,9 +35,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.StringUtils; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Aleksandr Tarasov (aatarasov) @@ -60,32 +57,35 @@ public class ConsulAutoServiceRegistrationManagementServiceTests { @Test public void contextLoads() { - final Response> response = consul.getAgentServices(); + final Response> response = this.consul.getAgentServices(); final Map services = response.getValue(); final Service service = services.get("myTestService-EE-0"); - assertNotNull("service was null", service); - assertNotEquals("service port was 0", 0, service.getPort().intValue()); - assertEquals("service id was wrong", "myTestService-EE-0", service.getId()); - assertEquals("service name was wrong", "myTestService-EE", service.getService()); - assertFalse("service address must not be empty", - StringUtils.isEmpty(service.getAddress())); - assertEquals("service address must equals hostname from discovery properties", - discoveryProperties.getHostname(), service.getAddress()); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port was 0").isNotEqualTo(0); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo("myTestService-EE-0"); + assertThat(service.getService()).as("service name was wrong") + .isEqualTo("myTestService-EE"); + assertThat(StringUtils.isEmpty(service.getAddress())) + .as("service address must not be empty").isFalse(); + assertThat(service.getAddress()) + .as("service address must equals hostname from discovery properties") + .isEqualTo(this.discoveryProperties.getHostname()); final Service managementService = services.get("myTestService-EE-0-management"); - assertNotNull("management service was null", managementService); - assertEquals("management service port was wrong", 4452, - managementService.getPort().intValue()); - assertEquals("management service id was wrong", "myTestService-EE-0-management", - managementService.getId()); - assertEquals("management service name was wrong", "myTestService-EE-management", - managementService.getService()); - assertFalse("management service address must not be empty", - StringUtils.isEmpty(managementService.getAddress())); - assertEquals( - "management service address must equals hostname from discovery properties", - discoveryProperties.getHostname(), managementService.getAddress()); + assertThat(managementService).as("management service was null").isNotNull(); + assertThat(managementService.getPort().intValue()) + .as("management service port was wrong").isEqualTo(4452); + assertThat(managementService.getId()).as("management service id was wrong") + .isEqualTo("myTestService-EE-0-management"); + assertThat(managementService.getService()).as("management service name was wrong") + .isEqualTo("myTestService-EE-management"); + assertThat(StringUtils.isEmpty(managementService.getAddress())) + .as("management service address must not be empty").isFalse(); + assertThat(managementService.getAddress()).as( + "management service address must equals hostname from discovery properties") + .isEqualTo(this.discoveryProperties.getHostname()); } @Configuration @@ -94,5 +94,7 @@ public class ConsulAutoServiceRegistrationManagementServiceTests { ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) public static class TestConfig { + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationNonWebTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationNonWebTests.java index 9337e61f..593cbf98 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationNonWebTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationNonWebTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -27,21 +31,16 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; /** * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConsulAutoServiceRegistrationNonWebTests.TestConfig.class, - properties = { "spring.application.name=consulNonWebTest", "server.port=32111" }, - webEnvironment = NONE) +@SpringBootTest(classes = ConsulAutoServiceRegistrationNonWebTests.TestConfig.class, properties = { + "spring.application.name=consulNonWebTest", + "server.port=32111" }, webEnvironment = NONE) public class ConsulAutoServiceRegistrationNonWebTests { @Autowired @@ -52,16 +51,22 @@ public class ConsulAutoServiceRegistrationNonWebTests { @Test public void contextLoads() { - assertNotNull("ConsulAutoServiceRegistration was created", autoServiceRegistration); + assertThat(this.autoServiceRegistration) + .as("ConsulAutoServiceRegistration was created").isNotNull(); - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); Service service = services.get("consulNonWebTest"); - assertNull("service was registered", service); //no port to listen, hence no registration + assertThat(service).as("service was registered").isNull(); // no port to listen, + // hence no + // registration } @EnableDiscoveryClient @Configuration @EnableAutoConfiguration - public static class TestConfig { } + public static class TestConfig { + + } + } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationRetryTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationRetryTests.java index bfd9bb6d..15ee2334 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationRetryTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationRetryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,24 +50,30 @@ public class ConsulAutoServiceRegistrationRetryTests { @Test public void testRetry() { this.exception.expect(ConsulException.class); - try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfig.class).properties("spring.application.name=testregistrationretry", - "spring.jmx.default-domain=testautoregretry", - "spring.cloud.consul.retry.max-attempts=2", - "logging.level.org.springframework.retry=DEBUG", - "server.port=0").run()) { - output.expect(Matchers.containsString("Retry: count=")); + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestConfig.class) + .properties("spring.application.name=testregistrationretry", + "spring.jmx.default-domain=testautoregretry", + "spring.cloud.consul.retry.max-attempts=2", + "logging.level.org.springframework.retry=DEBUG", + "server.port=0") + .run()) { + this.output.expect(Matchers.containsString("Retry: count=")); } } @SpringBootConfiguration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) protected static class TestConfig { @Bean public ConsulClient consulClient() { return new ConsulClient("localhost", 4321); } - } -} + } + +} diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationTests.java index 9f08ffde..3f31f819 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2019 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. @@ -18,8 +18,12 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Map; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.Response; +import com.ecwid.consul.v1.agent.model.Service; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -31,14 +35,7 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.StringUtils; -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.Service; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; import static org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration.normalizeForDns; @@ -47,8 +44,8 @@ import static org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistr * @author Venil Noronha */ @RunWith(SpringRunner.class) -@SpringBootTest(properties = { "spring.application.name=myTestService1-FF::something" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(properties = { + "spring.application.name=myTestService1-FF::something" }, webEnvironment = RANDOM_PORT) public class ConsulAutoServiceRegistrationTests { @Autowired @@ -62,23 +59,30 @@ public class ConsulAutoServiceRegistrationTests { @Test public void contextLoads() { - Response> response = consul.getAgentServices(); + Response> response = this.consul.getAgentServices(); Map services = response.getValue(); - Service service = services.get(registration.getInstanceId()); - assertNotNull("service was null", service); - assertNotEquals("service port is 0", 0, service.getPort().intValue()); - assertFalse("service id contained invalid character: " + service.getId(), service.getId().contains(":")); - assertEquals("service id was wrong", registration.getInstanceId(), service.getId()); - assertEquals("service name was wrong", "myTestService1-FF-something", service.getService()); - assertFalse("service address must not be empty", StringUtils.isEmpty(service.getAddress())); - assertEquals("service address must equals hostname from discovery properties", discoveryProperties.getHostname(), service.getAddress()); + Service service = services.get(this.registration.getInstanceId()); + assertThat(service).as("service was null").isNotNull(); + assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); + assertThat(service.getId().contains(":")) + .as("service id contained invalid character: " + service.getId()) + .isFalse(); + assertThat(service.getId()).as("service id was wrong") + .isEqualTo(this.registration.getInstanceId()); + assertThat(service.getService()).as("service name was wrong") + .isEqualTo("myTestService1-FF-something"); + assertThat(StringUtils.isEmpty(service.getAddress())) + .as("service address must not be empty").isFalse(); + assertThat(service.getAddress()) + .as("service address must equals hostname from discovery properties") + .isEqualTo(this.discoveryProperties.getHostname()); } @Test public void normalizeForDnsWorks() { - assertEquals("abc1", normalizeForDns("abc1")); - assertEquals("ab-c1", normalizeForDns("ab:c1")); - assertEquals("ab-c1", normalizeForDns("ab::c1")); + assertThat(normalizeForDns("abc1")).isEqualTo("abc1"); + assertThat(normalizeForDns("ab:c1")).isEqualTo("ab-c1"); + assertThat(normalizeForDns("ab::c1")).isEqualTo("ab-c1"); } @Test(expected = IllegalArgumentException.class) @@ -98,7 +102,11 @@ public class ConsulAutoServiceRegistrationTests { @SpringBootConfiguration @EnableAutoConfiguration - @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class }) - protected static class TestConfig { } -} + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) + protected static class TestConfig { + } + +} diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryCheckTtlTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryCheckTtlTests.java index 57e82ebc..76ae4142 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryCheckTtlTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryCheckTtlTests.java @@ -16,9 +16,13 @@ package org.springframework.cloud.consul.serviceregistry; +import java.lang.reflect.Field; +import java.util.Map; + import com.ecwid.consul.v1.agent.model.NewService; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -31,11 +35,7 @@ import org.springframework.cloud.consul.discovery.TtlScheduler; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import java.lang.reflect.Field; -import java.util.Map; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Alexey Savchuk @@ -43,8 +43,7 @@ import static org.junit.Assert.assertTrue; @RunWith(SpringRunner.class) @SpringBootTest(classes = ConsulServiceRegistryCheckTtlTests.TestConfig.class, properties = { "spring.application.name=myTestService-S", - "spring.cloud.consul.discovery.heartbeat.enabled=true" -}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + "spring.cloud.consul.discovery.heartbeat.enabled=true" }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class ConsulServiceRegistryCheckTtlTests { @LocalServerPort @@ -63,38 +62,42 @@ public class ConsulServiceRegistryCheckTtlTests { private TtlScheduler ttlScheduler; private ConsulRegistration createHttpRegistration() { - NewService service = registration.getService(); + NewService service = this.registration.getService(); NewService.Check httpCheck = new NewService.Check(); - httpCheck.setHttp(String.format( - "%s://%s:%s%s", - discoveryProperties.getScheme(), - discoveryProperties.getHostname(), - randomServerPort, - discoveryProperties.getHealthCheckPath() - )); - httpCheck.setInterval(discoveryProperties.getHealthCheckInterval()); + httpCheck.setHttp( + String.format("%s://%s:%s%s", this.discoveryProperties.getScheme(), + this.discoveryProperties.getHostname(), this.randomServerPort, + this.discoveryProperties.getHealthCheckPath())); + httpCheck.setInterval(this.discoveryProperties.getHealthCheckInterval()); NewService httpService = new NewService(); httpService.setId(service.getId() + "-http"); httpService.setName(service.getName() + "-http"); httpService.setCheck(httpCheck); - return new ConsulRegistration(httpService, discoveryProperties); + return new ConsulRegistration(httpService, this.discoveryProperties); } @Test public void contextLoads() throws NoSuchFieldException, IllegalAccessException { ConsulRegistration httpRegistration = createHttpRegistration(); - consulServiceRegistry.register(httpRegistration); - Field serviceHeartbeatsField = TtlScheduler.class.getDeclaredField("serviceHeartbeats"); + this.consulServiceRegistry.register(httpRegistration); + Field serviceHeartbeatsField = TtlScheduler.class + .getDeclaredField("serviceHeartbeats"); serviceHeartbeatsField.setAccessible(true); - Map serviceHeartbeats = (Map) serviceHeartbeatsField.get(ttlScheduler); - assertTrue("Service with heartbeat check not registered in TTL scheduler", serviceHeartbeats.keySet().contains(registration.getInstanceId())); - assertFalse("Service with HTTP check registered in TTL scheduler", serviceHeartbeats.keySet().contains(httpRegistration.getInstanceId())); + Map serviceHeartbeats = (Map) serviceHeartbeatsField.get(this.ttlScheduler); + assertThat(serviceHeartbeats.keySet().contains(this.registration.getInstanceId())) + .as("Service with heartbeat check not registered in TTL scheduler") + .isTrue(); + assertThat(serviceHeartbeats.keySet().contains(httpRegistration.getInstanceId())) + .as("Service with HTTP check registered in TTL scheduler").isFalse(); } @Configuration @EnableAutoConfiguration - @ImportAutoConfiguration({AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, ConsulAutoServiceRegistrationAutoConfiguration.class}) + @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, + ConsulAutoConfiguration.class, + ConsulAutoServiceRegistrationAutoConfiguration.class }) protected static class TestConfig { + } } diff --git a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryTests.java b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryTests.java index e3679d0c..8233e76f 100644 --- a/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryTests.java +++ b/spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2019 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. @@ -19,21 +19,21 @@ package org.springframework.cloud.consul.serviceregistry; import java.util.Collections; import java.util.List; +import com.ecwid.consul.v1.agent.model.NewService; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.consul.discovery.ConsulDiscoveryClient; import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.test.context.junit4.SpringRunner; -import com.ecwid.consul.v1.agent.model.NewService; - import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @@ -41,8 +41,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@SpringBootTest(properties = "spring.cloud.consul.discovery.query-passing=true", - webEnvironment = RANDOM_PORT) +@SpringBootTest(properties = "spring.cloud.consul.discovery.query-passing=true", webEnvironment = RANDOM_PORT) public class ConsulServiceRegistryTests { @Autowired(required = false) @@ -63,7 +62,8 @@ public class ConsulServiceRegistryTests { @Test public void contextLoads() { - assertThat(autoRegistration).as("autoRegistration created erroneously").isNull(); + assertThat(this.autoRegistration).as("autoRegistration created erroneously") + .isNull(); String serviceId = "myNonAutoRegisteredService"; @@ -71,28 +71,31 @@ public class ConsulServiceRegistryTests { service.setAddress("localhost"); service.setId("myNonAutoRegisteredService-A1"); service.setName(serviceId); - service.setPort(port); + service.setPort(this.port); service.setTags(Collections.singletonList("mytag")); - ConsulRegistration registration = new ConsulRegistration(service, this.properties); + ConsulRegistration registration = new ConsulRegistration(service, + this.properties); Throwable t = null; try { - serviceRegistry.register(registration); + this.serviceRegistry.register(registration); assertHasInstance(serviceId); assertStatus(registration, "UP"); // only works if query-passing = true - serviceRegistry.setStatus(registration, "OUT_OF_SERVICE"); + this.serviceRegistry.setStatus(registration, "OUT_OF_SERVICE"); assertEmptyInstances(serviceId); assertStatus(registration, "OUT_OF_SERVICE"); - serviceRegistry.setStatus(registration, "UP"); + this.serviceRegistry.setStatus(registration, "UP"); assertHasInstance(serviceId); - } catch (RuntimeException e) { - throw e ; - } finally { - serviceRegistry.deregister(registration); + } + catch (RuntimeException e) { + throw e; + } + finally { + this.serviceRegistry.deregister(registration); if (t == null) { // just deregister, test already failed assertEmptyInstances(serviceId); } @@ -101,12 +104,12 @@ public class ConsulServiceRegistryTests { } private void assertStatus(ConsulRegistration registration, String status) { - Object o = serviceRegistry.getStatus(registration); + Object o = this.serviceRegistry.getStatus(registration); assertThat(o).isEqualTo(status); } private void assertHasInstance(String serviceId) { - List instances = discoveryClient.getInstances(serviceId); + List instances = this.discoveryClient.getInstances(serviceId); assertThat(instances).hasSize(1); ServiceInstance instance = instances.get(0); @@ -114,13 +117,15 @@ public class ConsulServiceRegistryTests { } private void assertEmptyInstances(String serviceId) { - List instances = discoveryClient.getInstances(serviceId); + List instances = this.discoveryClient.getInstances(serviceId); assertThat(instances).isEmpty(); } @EnableDiscoveryClient(autoRegister = false) @SpringBootConfiguration @EnableAutoConfiguration - protected static class TestConfig { } -} + protected static class TestConfig { + } + +} diff --git a/spring-cloud-consul-sample/pom.xml b/spring-cloud-consul-sample/pom.xml index a060a20c..f65ef337 100644 --- a/spring-cloud-consul-sample/pom.xml +++ b/spring-cloud-consul-sample/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/spring-cloud-consul-sample/src/main/java/org/springframework/cloud/consul/sample/SampleConsulApplication.java b/spring-cloud-consul-sample/src/main/java/org/springframework/cloud/consul/sample/SampleConsulApplication.java index 86729546..5706d369 100644 --- a/spring-cloud-consul-sample/src/main/java/org/springframework/cloud/consul/sample/SampleConsulApplication.java +++ b/spring-cloud-consul-sample/src/main/java/org/springframework/cloud/consul/sample/SampleConsulApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2019 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. @@ -18,6 +18,8 @@ package org.springframework.cloud.consul.sample; import java.util.List; +import lombok.extern.slf4j.Slf4j; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; @@ -39,8 +41,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; -import lombok.extern.slf4j.Slf4j; - /** * @author Spencer Gibb */ @@ -50,7 +50,10 @@ import lombok.extern.slf4j.Slf4j; @EnableConfigurationProperties @EnableFeignClients @Slf4j -public class SampleConsulApplication /*implements ApplicationListener*/ { +public class SampleConsulApplication /* + * implements + * ApplicationListener + */ { @Autowired private LoadBalancerClient loadBalancer; @@ -73,6 +76,10 @@ public class SampleConsulApplication /*implements ApplicationListener instances() { - return discoveryClient.getInstances(appName); + return this.discoveryClient.getInstances(this.appName); } + /* + * @Bean public SubtypeModule sampleSubtypeModule() { return new + * SubtypeModule(SimpleRemoteEvent.class); } + */ + @RequestMapping("/feign") public String feign() { - return sampleClient.choose(); + return this.sampleClient.choose(); } - /*@Bean - public SubtypeModule sampleSubtypeModule() { - return new SubtypeModule(SimpleRemoteEvent.class); - }*/ - @Bean public SampleProperties sampleProperties() { return new SampleProperties(); @@ -129,20 +137,17 @@ public class SampleConsulApplication /*implements ApplicationListener - + 4.0.0 org.springframework.cloud diff --git a/spring-cloud-starter-consul-all/src/main/resources/META-INF/spring.provides b/spring-cloud-starter-consul-all/src/main/resources/META-INF/spring.provides index 18c222fc..7faec1ca 100644 --- a/spring-cloud-starter-consul-all/src/main/resources/META-INF/spring.provides +++ b/spring-cloud-starter-consul-all/src/main/resources/META-INF/spring.provides @@ -1 +1 @@ -provides: spring-cloud-consul-bus, spring-cloud-consul-config, spring-cloud-consul-discovery, spring-cloud-consul-ui \ No newline at end of file +provides: spring-cloud-consul-bus, spring-cloud-consul-config, spring-cloud-consul-discovery, spring-cloud-consul-ui diff --git a/spring-cloud-starter-consul-bus/pom.xml b/spring-cloud-starter-consul-bus/pom.xml index 3ce6fd81..b61e70b0 100644 --- a/spring-cloud-starter-consul-bus/pom.xml +++ b/spring-cloud-starter-consul-bus/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 org.springframework.cloud diff --git a/spring-cloud-starter-consul-bus/src/main/resources/META-INF/spring.provides b/spring-cloud-starter-consul-bus/src/main/resources/META-INF/spring.provides index 7e37bc1f..c6358bc1 100644 --- a/spring-cloud-starter-consul-bus/src/main/resources/META-INF/spring.provides +++ b/spring-cloud-starter-consul-bus/src/main/resources/META-INF/spring.provides @@ -1 +1 @@ -provides: spring-cloud-consul-bus \ No newline at end of file +provides: spring-cloud-consul-bus diff --git a/spring-cloud-starter-consul-config/pom.xml b/spring-cloud-starter-consul-config/pom.xml index d8556da2..03270d58 100644 --- a/spring-cloud-starter-consul-config/pom.xml +++ b/spring-cloud-starter-consul-config/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 org.springframework.cloud diff --git a/spring-cloud-starter-consul-config/src/main/resources/META-INF/spring.provides b/spring-cloud-starter-consul-config/src/main/resources/META-INF/spring.provides index 76b15afb..e7564ef7 100644 --- a/spring-cloud-starter-consul-config/src/main/resources/META-INF/spring.provides +++ b/spring-cloud-starter-consul-config/src/main/resources/META-INF/spring.provides @@ -1 +1 @@ -provides: spring-cloud-consul-config \ No newline at end of file +provides: spring-cloud-consul-config diff --git a/spring-cloud-starter-consul-discovery/pom.xml b/spring-cloud-starter-consul-discovery/pom.xml index efeac473..5ef278dd 100644 --- a/spring-cloud-starter-consul-discovery/pom.xml +++ b/spring-cloud-starter-consul-discovery/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/spring-cloud-starter-consul-discovery/src/main/resources/META-INF/spring.provides b/spring-cloud-starter-consul-discovery/src/main/resources/META-INF/spring.provides index 85fed12c..c0e57c89 100644 --- a/spring-cloud-starter-consul-discovery/src/main/resources/META-INF/spring.provides +++ b/spring-cloud-starter-consul-discovery/src/main/resources/META-INF/spring.provides @@ -1 +1 @@ -provides: spring-cloud-consul-discovery \ No newline at end of file +provides: spring-cloud-consul-discovery diff --git a/spring-cloud-starter-consul/pom.xml b/spring-cloud-starter-consul/pom.xml index ba32c33a..cc7a483b 100644 --- a/spring-cloud-starter-consul/pom.xml +++ b/spring-cloud-starter-consul/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 org.springframework.cloud diff --git a/spring-cloud-starter-consul/src/main/resources/META-INF/spring.provides b/spring-cloud-starter-consul/src/main/resources/META-INF/spring.provides index 174eee93..fe3abad3 100644 --- a/spring-cloud-starter-consul/src/main/resources/META-INF/spring.provides +++ b/spring-cloud-starter-consul/src/main/resources/META-INF/spring.provides @@ -1 +1 @@ -provides: spring-cloud-consul-core, consul-api \ No newline at end of file +provides: spring-cloud-consul-core, consul-api diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml new file mode 100644 index 00000000..34bb0712 --- /dev/null +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/src/main/bash/travis_install_consul.sh b/src/main/bash/travis_install_consul.sh index 588275ac..f5909ceb 100755 --- a/src/main/bash/travis_install_consul.sh +++ b/src/main/bash/travis_install_consul.sh @@ -1,6 +1,6 @@ #!/bin/bash -CONSUL_VER="0.7.5" +CONSUL_VER="1.4.2" CONSUL_ZIP="consul_${CONSUL_VER}_linux_amd64.zip" IGNORE_CERTS="${IGNORE_CERTS:-no}" diff --git a/src/test/resources/consul_acl/consul_anonymous_acl.json b/src/test/resources/consul_acl/consul_anonymous_acl.json index 61745b11..6d00484e 100644 --- a/src/test/resources/consul_acl/consul_anonymous_acl.json +++ b/src/test/resources/consul_acl/consul_anonymous_acl.json @@ -1,28 +1,31 @@ { - "ID": "anonymous", - "Name": "anonymous", - "Type": "client", - "Rules": "{ - \"key\": { - \"\": { - \"policy\": \"write\" - } - }, - \"event\": { - \"\": { - \"policy\": \"write\" - } - }, - \"service\": { - \"\": { - \"policy\": \"write\" - }, - \"testConsulDiscoveryAcl\": { - \"policy\": \"deny\" - }, - \"testConsulDiscoveryAcl\": { - \"policy\": \"deny\" - } - } - }" + "ID": "anonymous", + "Name": "anonymous", + "Type": "client", + "Rules": "{ + \ + "key\": { + \ + "\": { + \ + "policy\": \"write\" +} +}, +\"event\": { +\"\": { +\"policy\": \"write\" +} +}, +\"service\": { +\"\": { +\"policy\": \"write\" +}, +\"testConsulDiscoveryAcl\": { +\"policy\": \"deny\" +}, +\"testConsulDiscoveryAcl\": { +\"policy\": \"deny\" +} +} +}" } diff --git a/src/test/resources/consul_acl/consul_discovery_client_acl.json b/src/test/resources/consul_acl/consul_discovery_client_acl.json index 7af310a1..6ff52993 100644 --- a/src/test/resources/consul_acl/consul_discovery_client_acl.json +++ b/src/test/resources/consul_acl/consul_discovery_client_acl.json @@ -1,18 +1,21 @@ { - "ID": "2d2e6b3b-1c82-40ab-8171-54609d8ad304", - "Name": "discover_client_test_acl", - "Type": "client", - "Rules": "{ - \"service\": { - \"\": { - \"policy\": \"write\" - }, - \"testConsulDiscoveryAcl\": { - \"policy\": \"write\" - }, - \"testSecondServiceAcl\": { - \"policy\": \"write\" - } - } - }" + "ID": "2d2e6b3b-1c82-40ab-8171-54609d8ad304", + "Name": "discover_client_test_acl", + "Type": "client", + "Rules": "{ + \ + "service\": { + \ + "\": { + \ + "policy\": \"write\" +}, +\"testConsulDiscoveryAcl\": { +\"policy\": \"write\" +}, +\"testSecondServiceAcl\": { +\"policy\": \"write\" +} +} +}" } diff --git a/src/test/resources/consul_config/acl_config.json b/src/test/resources/consul_config/acl_config.json index ea9e761b..344f5a6a 100644 --- a/src/test/resources/consul_config/acl_config.json +++ b/src/test/resources/consul_config/acl_config.json @@ -1,6 +1,6 @@ { - "datacenter": "local", - "acl_datacenter": "local", - "acl_master_token": "2ee647bd-bd69-4118-9f34-b9a6e9e60746", - "acl_default_policy": "deny" + "datacenter": "local", + "acl_datacenter": "local", + "acl_master_token": "2ee647bd-bd69-4118-9f34-b9a6e9e60746", + "acl_default_policy": "deny" } diff --git a/src/test/resources/consul_ui/index.html b/src/test/resources/consul_ui/index.html index bfd9bf4c..bd9aa8f4 100644 --- a/src/test/resources/consul_ui/index.html +++ b/src/test/resources/consul_ui/index.html @@ -1,40 +1,43 @@ - - - - Consul by HashiCorp - - - + + + + Consul by HashiCorp + + + -
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
- + - - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + - + + + + + diff --git a/src/test/resources/consul_ui/static/application.min.js b/src/test/resources/consul_ui/static/application.min.js index 4055c2ba..413431fe 100644 --- a/src/test/resources/consul_ui/static/application.min.js +++ b/src/test/resources/consul_ui/static/application.min.js @@ -364,4 +364,4 @@ if ( typeof define === 'function' && define.amd ) { window.NotificationFx = NotificationFx; } )( window ); -window.App=Ember.Application.create({rootElement:"#app",currentPath:""}),Ember.Application.initializer({name:"settings",initialize:function(t,e){e.set("settings",App.Settings.create()),void 0===App.get("settings.token")&&App.set("settings.token","")}}),App.Router.map(function(){this.resource("dc",{path:"/:dc"},function(){this.resource("services",{path:"/services"},function(){this.route("show",{path:"/*name"})}),this.resource("nodes",{path:"/nodes"},function(){this.route("show",{path:"/:name"})}),this.resource("kv",{path:"/kv"},function(){this.route("index",{path:"/"}),this.route("show",{path:"/*key"}),this.route("edit",{path:"/*key/edit"})}),this.resource("acls",{path:"/acls"},function(){this.route("show",{path:"/:id"})}),this.route("aclsdisabled",{path:"/aclsdisabled"}),this.route("unauthorized",{path:"/unauthorized"}),this.resource("settings",{path:"/settings"})}),this.route("index",{path:"/"})});App.Service=Ember.Object.extend({failingChecks:function(){if(void 0!==this.get("ChecksCritical"))return this.get("ChecksCritical")+this.get("ChecksWarning");var e=this.get("Checks");return e.filterBy("Status","critical").get("length")+e.filterBy("Status","warning").get("length")}.property("Checks"),passingChecks:function(){return void 0!==this.get("ChecksPassing")?this.get("ChecksPassing"):this.get("Checks").filterBy("Status","passing").get("length")}.property("Checks"),checkMessage:function(){return this.get("hasFailingChecks")===!1?this.get("passingChecks")+" passing":this.get("failingChecks")+" failing"}.property("Checks"),nodes:function(){return this.get("Nodes")}.property("Nodes"),hasFailingChecks:Ember.computed.gt("failingChecks",0),filterKey:Ember.computed.alias("Name")}),App.Node=Ember.Object.extend({failingChecks:function(){return this.get("Checks").reduce(function(e,t){var r=Ember.get(t,"Status");return"critical"===r||"warning"===r?e+1:e},0)}.property("Checks"),passingChecks:function(){return this.get("Checks").filterBy("Status","passing").get("length")}.property("Checks"),checkMessage:function(){return this.get("hasFailingChecks")===!1?this.get("passingChecks")+" passing":this.get("failingChecks")+" failing"}.property("Checks"),hasFailingChecks:Ember.computed.gt("failingChecks",0),numServices:Ember.computed.alias("Services.length"),services:Ember.computed.alias("Services"),filterKey:Ember.computed.alias("Node")}),App.Key=Ember.Object.extend(Ember.Validations.Mixin,{validations:{Key:{presence:!0}},keyValid:Ember.computed.empty("errors.Key"),valueValid:Ember.computed.empty("errors.Value"),keyWithoutParent:function(){return this.get("Key").replace(this.get("parentKey"),"")}.property("Key"),isFolder:function(){return void 0===this.get("Key")?!1:"/"===this.get("Key").slice(-1)}.property("Key"),isLocked:function(){return this.get("Session")?!0:!1}.property("Session"),linkToRoute:function(){return"/"===this.get("Key").slice(-1)?"kv.show":"kv.edit"}.property("Key"),valueDecoded:function(e,t){return arguments.length>1?(this.set("Value",t),t):null===this.get("Value")?"":(Base64.extendString&&Base64.extendString(),this.get("Value").fromBase64())}.property("Value"),keyParts:function(){var e=this.get("Key");return"/"==e.slice(-1)&&(e=e.substring(0,e.length-1)),e.split("/")}.property("Key"),parentKey:function(){var e=this.get("keyParts").toArray();return e.pop(),e.join("/")+"/"}.property("Key"),grandParentKey:function(){var e=this.get("keyParts").toArray();return e.pop(),e.pop(),e.join("/")+"/"}.property("Key")}),App.Acl=Ember.Object.extend({isNotAnon:function(){return"anonymous"===this.get("ID")?!1:!0}.property("ID")}),App.Settings=Ember.Object.extend({unknownProperty:function(e){return localStorage[e]},setUnknownProperty:function(e,t){return Ember.isNone(t)?delete localStorage[e]:localStorage[e]=t,this.notifyPropertyChange(e),t},clear:function(){this.beginPropertyChanges();for(var e=0,t=localStorage.length;t>e;e++)this.set(localStorage.key(e));localStorage.clear(),this.endPropertyChanges()}});function formatUrl(e,t,n){return null==n&&(n=""),e.indexOf("?")>0?(e=e+"&dc="+t,e=e+"&token="+n):(e=e+"?dc="+t,e=e+"&token="+n),e}App.BaseRoute=Ember.Route.extend({rootKey:"",condensedView:!1,queryParams:{filter:{replace:!0}},getParentAndGrandparent:function(e){var t=this.rootKey,n=this.rootKey,o=e.split("/");return o.length>0&&(o.pop(),t=o.join("/")+"/"),o.length>1&&(o.pop(),n=o.join("/")+"/"),{parent:t,grandParent:n,isRoot:"/"===t}},removeDuplicateKeys:function(e,t){return e.forEach(function(n,o){n.get("Key")==t&&e.splice(o,1)}),e},actions:{linkToKey:function(e){"/"==e?this.transitionTo("kv.show",""):"/"===e.slice(-1)||e===this.rootKey?this.transitionTo("kv.show",e):this.transitionTo("kv.edit",e)}}}),App.IndexRoute=App.BaseRoute.extend({model:function(){return Ember.$.getJSON("/v1/catalog/datacenters").then(function(e){return e})},afterModel:function(e){1===e.get("length")&&this.transitionTo("services",e[0])}}),App.DcRoute=App.BaseRoute.extend({model:function(e){var t=App.get("settings.token");return Ember.RSVP.hash({dc:e.dc,dcs:Ember.$.getJSON("/v1/catalog/datacenters"),nodes:Ember.$.getJSON(formatUrl("/v1/internal/ui/nodes",e.dc,t)).then(function(e){var t=[];return e.map(function(e){t.push(App.Node.create(e))}),t})})},setupController:function(e,t){e.set("content",t.dc),e.set("nodes",t.nodes),e.set("dcs",t.dcs),e.set("isDropdownVisible",!1)}}),App.KvIndexRoute=App.BaseRoute.extend({beforeModel:function(){this.transitionTo("kv.show",this.rootKey)}}),App.KvShowRoute=App.BaseRoute.extend({model:function(e){var t=e.key,n=this.modelFor("dc").dc,o=App.get("settings.token");return Ember.RSVP.hash({key:t,keys:Ember.$.getJSON(formatUrl("/v1/kv/"+t+"?keys&seperator=/",n,o)).then(function(e){var t=[];return e.map(function(e){t.push(App.Key.create({Key:e}))}),t})})},setupController:function(e,t){var n=t.key,o=this.getParentAndGrandparent(n);t.keys=this.removeDuplicateKeys(t.keys,t.key),e.set("content",t.keys),e.set("parentKey",o.parent),e.set("grandParentKey",o.grandParent),e.set("isRoot",o.isRoot),e.set("newKey",App.Key.create()),e.set("rootKey",this.rootKey)}}),App.KvEditRoute=App.BaseRoute.extend({model:function(e){var t=e.key,n=this.modelFor("dc").dc,o=this.getParentAndGrandparent(t),r=App.get("settings.token");return Ember.RSVP.hash({dc:n,token:r,key:Ember.$.getJSON(formatUrl("/v1/kv/"+t,n,r)).then(function(e){return App.Key.create().setProperties(e[0])}),keys:keysPromise=Ember.$.getJSON(formatUrl("/v1/kv/"+o.parent+"?keys&seperator=/",n,r)).then(function(e){var t=[];return e.map(function(e){t.push(App.Key.create({Key:e}))}),t})})},afterModel:function(e){return e.key.get("isLocked")?Ember.$.getJSON(formatUrl("/v1/session/info/"+e.key.Session,e.dc,e.token)).then(function(t){return e.session=t[0],e}):e},setupController:function(e,t){var n=t.key,o=this.getParentAndGrandparent(n.get("Key"));t.keys=this.removeDuplicateKeys(t.keys,o.parent),e.set("content",t.key),e.set("parentKey",o.parent),e.set("grandParentKey",o.grandParent),e.set("isRoot",o.isRoot),e.set("siblings",t.keys),e.set("rootKey",this.rootKey),e.set("session",t.session)}}),App.ServicesRoute=App.BaseRoute.extend({model:function(){var e=this.modelFor("dc").dc,t=App.get("settings.token");return Ember.$.getJSON(formatUrl("/v1/internal/ui/services",e,t)).then(function(e){var t=[];return e.map(function(e){t.push(App.Service.create(e))}),t})},setupController:function(e,t){e.set("services",t)}}),App.ServicesShowRoute=App.BaseRoute.extend({model:function(e){var t=this.modelFor("dc").dc,n=App.get("settings.token");return Ember.$.getJSON(formatUrl("/v1/health/service/"+e.name,t,n)).then(function(e){var t=[];return e.map(function(e){t.push(App.Node.create(e))}),t})},setupController:function(e,t){var n=[];t.map(function(e){n=n.concat(e.Service.Tags)}),n=n.filter(function(e){return void 0!==e}),n=n.uniq().join(", "),e.set("content",t),e.set("tags",n)}}),App.NodesShowRoute=App.BaseRoute.extend({model:function(e){var t=this.modelFor("dc").dc,n=App.get("settings.token");return Ember.RSVP.hash({dc:t,token:n,node:Ember.$.getJSON(formatUrl("/v1/internal/ui/node/"+e.name,t,n)).then(function(e){return App.Node.create(e)}),nodes:Ember.$.getJSON(formatUrl("/v1/internal/ui/node/"+e.name,t,n)).then(function(e){return App.Node.create(e)})})},afterModel:function(e){return Ember.$.getJSON(formatUrl("/v1/session/node/"+e.node.Node,e.dc,e.token)).then(function(t){return e.sessions=t,e})},setupController:function(e,t){e.set("content",t.node),e.set("sessions",t.sessions),e.set("nodes",t.nodes)}}),App.NodesRoute=App.BaseRoute.extend({model:function(){var e=this.modelFor("dc").dc,t=App.get("settings.token");return Ember.$.getJSON(formatUrl("/v1/internal/ui/nodes",e,t)).then(function(e){var t=[];return e.map(function(e){t.push(App.Node.create(e))}),t})},setupController:function(e,t){e.set("nodes",t)}}),App.AclsRoute=App.BaseRoute.extend({model:function(){var e=this.modelFor("dc").dc,t=App.get("settings.token");return Ember.$.getJSON(formatUrl("/v1/acl/list",e,t)).then(function(e){var t=[];return e.map(function(e){"anonymous"===e.ID?t.unshift(App.Acl.create(e)):t.push(App.Acl.create(e))}),t})},actions:{error:function(e){return e&&401===e.status?this.transitionTo("dc.aclsdisabled"):e&&403===e.status&&this.transitionTo("dc.unauthorized"),!0}},setupController:function(e,t){e.set("acls",t),e.set("newAcl",App.Acl.create())}}),App.AclsShowRoute=App.BaseRoute.extend({model:function(e){var t=this.modelFor("dc").dc,n=App.get("settings.token");return Ember.RSVP.hash({dc:t,acl:Ember.$.getJSON(formatUrl("/v1/acl/info/"+e.id,t,n)).then(function(e){return App.Acl.create(e[0])})})},setupController:function(e,t){e.set("content",t.acl)}}),App.SettingsRoute=App.BaseRoute.extend({model:function(){return App.get("settings")}});App.ApplicationController=Ember.ObjectController.extend({updateCurrentPath:function(){App.set("currentPath",this.get("currentPath"))}.observes("currentPath")}),App.DcController=Ember.Controller.extend({needs:["application"],isDropdownVisible:!1,datacenter:Ember.computed.alias("content"),totalChecksFailing:function(){return this.get("nodes").reduce(function(e,t){return e+t.get("failingChecks")},0)}.property("nodes"),totalChecksPassing:function(){return this.get("nodes").reduce(function(e,t){return e+t.get("passingChecks")},0)}.property("nodes"),checkMessage:function(){var e=this.get("totalChecksFailing"),t=this.get("totalChecksPassing");return this.get("hasFailingChecks")===!0?e+" failing":t+" passing"}.property("nodes"),checkStatus:function(){return this.get("hasFailingChecks")===!0?"failing":"passing"}.property("nodes"),hasFailingChecks:Ember.computed.gt("totalChecksFailing",0),actions:{toggle:function(){this.toggleProperty("isDropdownVisible")},hideDrop:function(){this.set("isDropdownVisible",!1)}}}),KvBaseController=Ember.ObjectController.extend({getParentKeyRoute:function(){return this.get(this.get("isRoot")?"rootKey":"parentKey")},transitionToNearestParent:function(e){var t=this,n=t.get("rootKey"),s=t.get("dc").get("datacenter"),o=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/kv/"+e+"?keys",s,o),type:"GET"}).then(function(){t.transitionToRoute("kv.show",e)}).fail(function(e){404===e.status&&t.transitionToRoute("kv.show",n)}),t.set("isLoading",!1)}}),App.KvShowController=KvBaseController.extend(Ember.Validations.Mixin,{needs:["dc"],dc:Ember.computed.alias("controllers.dc"),isLoading:!1,actions:{createKey:function(){this.set("isLoading",!0);var e=this,t=e.get("newKey"),n=e.get("parentKey"),s=(e.get("grandParentKey"),e.get("dc").get("datacenter")),o=App.get("settings.token");void 0!==n&&"/"!==n&&t.set("Key",n+t.get("Key")),Ember.$.ajax({url:formatUrl("/v1/kv/"+t.get("Key"),s,o),type:"PUT",data:t.get("Value")}).then(function(){t.get("isFolder")===!0?e.transitionToRoute("kv.show",t.get("Key")):e.transitionToRoute("kv.edit",t.get("Key")),e.set("isLoading",!1)}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText)})},deleteFolder:function(){this.set("isLoading",!0);var e=this,t=e.get("dc").get("datacenter"),n=e.get("grandParentKey"),s=App.get("settings.token");window.confirm("Are you sure you want to delete this folder?")&&Ember.$.ajax({url:formatUrl("/v1/kv/"+e.get("parentKey")+"?recurse",t,s),type:"DELETE"}).then(function(){e.transitionToNearestParent(n)}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText)})}}}),App.KvEditController=KvBaseController.extend({isLoading:!1,needs:["dc"],dc:Ember.computed.alias("controllers.dc"),actions:{updateKey:function(){this.set("isLoading",!0);var e=this.get("dc").get("datacenter"),t=this.get("model"),n=this,s=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/kv/"+t.get("Key"),e,s),type:"PUT",data:t.get("valueDecoded")}).then(function(){n.set("isLoading",!1)}).fail(function(e){n.set("errorMessage","Received error while processing: "+e.statusText)})},cancelEdit:function(){this.set("isLoading",!0),this.transitionToRoute("kv.show",this.getParentKeyRoute()),this.set("isLoading",!1)},deleteKey:function(){this.set("isLoading",!0);var e=this,t=e.get("dc").get("datacenter"),n=e.get("model"),s=e.getParentKeyRoute(),o=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/kv/"+n.get("Key"),t,o),type:"DELETE"}).then(function(){e.transitionToNearestParent(s)}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText)})}}}),ItemBaseController=Ember.ArrayController.extend({needs:["dc","application"],queryParams:["filter","status","condensed"],dc:Ember.computed.alias("controllers.dc"),condensed:!0,hasExpanded:!0,filterText:"Filter by name",filter:"",status:"any status",statuses:["any status","passing","failing"],isShowingItem:function(){var e=this.get("controllers.application.currentPath");return"dc.nodes.show"===e||"dc.services.show"===e}.property("controllers.application.currentPath"),filteredContent:function(){var e=this.get("filter"),t=this.get("status"),n=this.get("items").filter(function(t){return t.get("filterKey").toLowerCase().match(e.toLowerCase())});switch(t){case"passing":return n.filterBy("hasFailingChecks",!1);case"failing":return n.filterBy("hasFailingChecks",!0);default:return n}}.property("filter","status","items.@each"),actions:{toggleCondensed:function(){this.toggleProperty("condensed")}}}),App.NodesShowController=Ember.ObjectController.extend({needs:["dc","nodes"],dc:Ember.computed.alias("controllers.dc"),actions:{deregisterNode:function(){this.set("isLoading",!0);var e=this,t=e.get("model"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");window.confirm("Are you sure you want to deregister this node?")&&Ember.$.ajax({url:formatUrl("/v1/catalog/deregister",n,s),type:"PUT",data:JSON.stringify({Datacenter:n,Node:t.Node})}).then(function(){var n=e.get("controllers.nodes").get("nodes");e.get("controllers.nodes").set("nodes",n.filter(function(e){return e.Node!==t.Node})),e.transitionToRoute("nodes")}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText)})},invalidateSession:function(e){this.set("isLoading",!0);var t=this,n=t.get("model"),s=t.get("dc").get("datacenter"),o=App.get("settings.token");window.confirm("Are you sure you want to invalidate this session?")&&Ember.$.ajax({url:formatUrl("/v1/session/destroy/"+e,s,o),type:"PUT"}).then(function(){return Ember.$.getJSON(formatUrl("/v1/session/node/"+n.Node,s,o)).then(function(e){t.set("sessions",e)})}).fail(function(e){t.set("errorMessage","Received error while processing: "+e.statusText)})}}}),App.NodesController=ItemBaseController.extend({items:Ember.computed.alias("nodes")}),App.ServicesController=ItemBaseController.extend({items:Ember.computed.alias("services")}),App.AclsController=Ember.ArrayController.extend({needs:["dc","application"],queryParams:["filter"],filterText:"Filter by name or ID",searchBar:!0,newAclButton:!0,types:["management","client"],dc:Ember.computed.alias("controllers.dc"),items:Ember.computed.alias("acls"),filter:"",isShowingItem:function(){var e=this.get("controllers.application.currentPath");return"dc.acls.show"===e}.property("controllers.application.currentPath"),filteredContent:function(){var e=this.get("filter"),t=this.get("items").filter(function(t){var n=t.get("Name").toLowerCase().match(e.toLowerCase());return null!==n?n:t.get("ID").toLowerCase().match(e.toLowerCase())});return t}.property("filter","items.@each"),actions:{createAcl:function(){this.set("isLoading",!0);var e=this,t=e.get("newAcl"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/acl/create",n,s),type:"PUT",data:JSON.stringify(t)}).then(function(t){e.transitionToRoute("acls.show",t.ID),Ember.$.getJSON(formatUrl("/v1/acl/list",n,s)).then(function(t){var n=[];t.map(function(e){n.push(App.Acl.create(e))}),e.set("items",n)}),e.set("isLoading",!1)}).fail(function(t){notify("Received error while creating ACL: "+t.statusText,8e3),e.set("isLoading",!1)})}}}),App.AclsShowController=Ember.ObjectController.extend({needs:["dc","acls"],dc:Ember.computed.alias("controllers.dc"),isLoading:!1,types:["management","client"],actions:{set:function(){this.set("isLoading",!0);{var e=this,t=e.get("model");e.get("dc").get("datacenter")}if(window.confirm("Are you sure you want to use this token for your session?")){{App.set("settings.token",t.ID)}e.transitionToRoute("services"),this.set("isLoading",!1),notify("Now using token: "+t.ID,3e3)}},clone:function(){this.set("isLoading",!0);var e=this,t=e.get("model"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");e.transitionToRoute("services"),Ember.$.ajax({url:formatUrl("/v1/acl/clone/"+t.ID,n,s),type:"PUT"}).then(function(t){e.transitionToRoute("acls.show",t.ID),e.set("isLoading",!1),notify("Successfully cloned token",4e3)}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText),e.set("isLoading",!1)})},"delete":function(){this.set("isLoading",!0);var e=this,t=e.get("model"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");window.confirm("Are you sure you want to delete this token?")&&Ember.$.ajax({url:formatUrl("/v1/acl/destroy/"+t.ID,n,s),type:"PUT"}).then(function(){Ember.$.getJSON(formatUrl("/v1/acl/list",n,s)).then(function(t){objs=[],t.map(function(e){"anonymous"===e.ID?objs.unshift(App.Acl.create(e)):objs.push(App.Acl.create(e))}),e.get("controllers.acls").set("acls",objs)}).then(function(){e.transitionToRoute("acls"),e.set("isLoading",!1),notify("ACL deleted successfully",3e3)})}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText),e.set("isLoading",!1)})},updateAcl:function(){this.set("isLoading",!0);var e=this,t=e.get("model"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/acl/update",n,s),type:"PUT",data:JSON.stringify(t)}).then(function(){e.set("isLoading",!1),notify("ACL updated successfully",3e3)}).fail(function(t){notify("Received error while updating ACL: "+t.statusText,8e3),e.set("isLoading",!1)})}}}),App.SettingsController=Ember.ObjectController.extend({actions:{reset:function(){this.set("isLoading",!0);var e=this;window.confirm("Are your sure you want to reset your settings?")&&(localStorage.clear(),e.set("content",App.Settings.create()),App.set("settings.token",""),notify("Settings reset",3e3),this.set("isLoading",!1))}}});App.DcView=Ember.View.extend({templateName:"dc",classNames:"dropdowns",click:function(e){$(e.target).is(".dropdowns")&&$("ul.dropdown-menu").hide()}}),App.ItemView=Ember.View.extend({templateName:"item"}),App.ServicesView=Ember.View.extend({templateName:"services"}),App.ServicesShowView=Ember.View.extend({templateName:"service"}),App.ServicesLoadingView=Ember.View.extend({templateName:"item/loading"}),App.NodesView=Ember.View.extend({templateName:"nodes"}),App.NodesShowView=Ember.View.extend({templateName:"node"}),App.NodesLoadingView=Ember.View.extend({templateName:"item/loading"}),App.KvListView=Ember.View.extend({templateName:"kv"}),App.ActionBarView=Ember.View.extend({templateName:"actionbar"}),App.AclView=Ember.View.extend({templateName:"acls"}),App.AclsShowView=Ember.View.extend({templateName:"acl"}),App.SettingsView=Ember.View.extend({templateName:"settings"});function notify(e,a){void 0!==window.notifications&&window.notifications.length>0&&$(window.notifications).each(function(e,a){a.dismiss()});var n=new NotificationFx({message:"

"+e+"

",layout:"growl",effect:"slide",type:"notice",ttl:a});n.show(),window.notifications=[],window.notifications.push(n)}Ember.Handlebars.helper("panelBar",function(e){var a;return a="passing"==e?"bg-green":"bg-orange",new Handlebars.SafeString('
')}),Ember.Handlebars.helper("listBar",function(e){var a;return a="passing"==e?"bg-green":"bg-orange",new Handlebars.SafeString('
')}),Ember.Handlebars.helper("sessionName",function(e){var a;return a=""===e.Name?""+e.ID+"":""+e.Name+" "+e.ID+"",new Handlebars.SafeString(a)}),Ember.Handlebars.helper("sessionMeta",function(e){var a='";return""!==e.TTL&&(a=a+'"),new Handlebars.SafeString(a)}),Ember.Handlebars.helper("aclName",function(e,a){return""===e?a:new Handlebars.SafeString(e+' '+a+"")}),Ember.Handlebars.helper("formatRules",function(e){return""===e?"No rules defined":e}),Ember.Handlebars.helper("serviceTagMessage",function(e){return null===e?"No tags":void 0}); \ No newline at end of file +window.App=Ember.Application.create({rootElement:"#app",currentPath:""}),Ember.Application.initializer({name:"settings",initialize:function(t,e){e.set("settings",App.Settings.create()),void 0===App.get("settings.token")&&App.set("settings.token","")}}),App.Router.map(function(){this.resource("dc",{path:"/:dc"},function(){this.resource("services",{path:"/services"},function(){this.route("show",{path:"/*name"})}),this.resource("nodes",{path:"/nodes"},function(){this.route("show",{path:"/:name"})}),this.resource("kv",{path:"/kv"},function(){this.route("index",{path:"/"}),this.route("show",{path:"/*key"}),this.route("edit",{path:"/*key/edit"})}),this.resource("acls",{path:"/acls"},function(){this.route("show",{path:"/:id"})}),this.route("aclsdisabled",{path:"/aclsdisabled"}),this.route("unauthorized",{path:"/unauthorized"}),this.resource("settings",{path:"/settings"})}),this.route("index",{path:"/"})});App.Service=Ember.Object.extend({failingChecks:function(){if(void 0!==this.get("ChecksCritical"))return this.get("ChecksCritical")+this.get("ChecksWarning");var e=this.get("Checks");return e.filterBy("Status","critical").get("length")+e.filterBy("Status","warning").get("length")}.property("Checks"),passingChecks:function(){return void 0!==this.get("ChecksPassing")?this.get("ChecksPassing"):this.get("Checks").filterBy("Status","passing").get("length")}.property("Checks"),checkMessage:function(){return this.get("hasFailingChecks")===!1?this.get("passingChecks")+" passing":this.get("failingChecks")+" failing"}.property("Checks"),nodes:function(){return this.get("Nodes")}.property("Nodes"),hasFailingChecks:Ember.computed.gt("failingChecks",0),filterKey:Ember.computed.alias("Name")}),App.Node=Ember.Object.extend({failingChecks:function(){return this.get("Checks").reduce(function(e,t){var r=Ember.get(t,"Status");return"critical"===r||"warning"===r?e+1:e},0)}.property("Checks"),passingChecks:function(){return this.get("Checks").filterBy("Status","passing").get("length")}.property("Checks"),checkMessage:function(){return this.get("hasFailingChecks")===!1?this.get("passingChecks")+" passing":this.get("failingChecks")+" failing"}.property("Checks"),hasFailingChecks:Ember.computed.gt("failingChecks",0),numServices:Ember.computed.alias("Services.length"),services:Ember.computed.alias("Services"),filterKey:Ember.computed.alias("Node")}),App.Key=Ember.Object.extend(Ember.Validations.Mixin,{validations:{Key:{presence:!0}},keyValid:Ember.computed.empty("errors.Key"),valueValid:Ember.computed.empty("errors.Value"),keyWithoutParent:function(){return this.get("Key").replace(this.get("parentKey"),"")}.property("Key"),isFolder:function(){return void 0===this.get("Key")?!1:"/"===this.get("Key").slice(-1)}.property("Key"),isLocked:function(){return this.get("Session")?!0:!1}.property("Session"),linkToRoute:function(){return"/"===this.get("Key").slice(-1)?"kv.show":"kv.edit"}.property("Key"),valueDecoded:function(e,t){return arguments.length>1?(this.set("Value",t),t):null===this.get("Value")?"":(Base64.extendString&&Base64.extendString(),this.get("Value").fromBase64())}.property("Value"),keyParts:function(){var e=this.get("Key");return"/"==e.slice(-1)&&(e=e.substring(0,e.length-1)),e.split("/")}.property("Key"),parentKey:function(){var e=this.get("keyParts").toArray();return e.pop(),e.join("/")+"/"}.property("Key"),grandParentKey:function(){var e=this.get("keyParts").toArray();return e.pop(),e.pop(),e.join("/")+"/"}.property("Key")}),App.Acl=Ember.Object.extend({isNotAnon:function(){return"anonymous"===this.get("ID")?!1:!0}.property("ID")}),App.Settings=Ember.Object.extend({unknownProperty:function(e){return localStorage[e]},setUnknownProperty:function(e,t){return Ember.isNone(t)?delete localStorage[e]:localStorage[e]=t,this.notifyPropertyChange(e),t},clear:function(){this.beginPropertyChanges();for(var e=0,t=localStorage.length;t>e;e++)this.set(localStorage.key(e));localStorage.clear(),this.endPropertyChanges()}});function formatUrl(e,t,n){return null==n&&(n=""),e.indexOf("?")>0?(e=e+"&dc="+t,e=e+"&token="+n):(e=e+"?dc="+t,e=e+"&token="+n),e}App.BaseRoute=Ember.Route.extend({rootKey:"",condensedView:!1,queryParams:{filter:{replace:!0}},getParentAndGrandparent:function(e){var t=this.rootKey,n=this.rootKey,o=e.split("/");return o.length>0&&(o.pop(),t=o.join("/")+"/"),o.length>1&&(o.pop(),n=o.join("/")+"/"),{parent:t,grandParent:n,isRoot:"/"===t}},removeDuplicateKeys:function(e,t){return e.forEach(function(n,o){n.get("Key")==t&&e.splice(o,1)}),e},actions:{linkToKey:function(e){"/"==e?this.transitionTo("kv.show",""):"/"===e.slice(-1)||e===this.rootKey?this.transitionTo("kv.show",e):this.transitionTo("kv.edit",e)}}}),App.IndexRoute=App.BaseRoute.extend({model:function(){return Ember.$.getJSON("/v1/catalog/datacenters").then(function(e){return e})},afterModel:function(e){1===e.get("length")&&this.transitionTo("services",e[0])}}),App.DcRoute=App.BaseRoute.extend({model:function(e){var t=App.get("settings.token");return Ember.RSVP.hash({dc:e.dc,dcs:Ember.$.getJSON("/v1/catalog/datacenters"),nodes:Ember.$.getJSON(formatUrl("/v1/internal/ui/nodes",e.dc,t)).then(function(e){var t=[];return e.map(function(e){t.push(App.Node.create(e))}),t})})},setupController:function(e,t){e.set("content",t.dc),e.set("nodes",t.nodes),e.set("dcs",t.dcs),e.set("isDropdownVisible",!1)}}),App.KvIndexRoute=App.BaseRoute.extend({beforeModel:function(){this.transitionTo("kv.show",this.rootKey)}}),App.KvShowRoute=App.BaseRoute.extend({model:function(e){var t=e.key,n=this.modelFor("dc").dc,o=App.get("settings.token");return Ember.RSVP.hash({key:t,keys:Ember.$.getJSON(formatUrl("/v1/kv/"+t+"?keys&seperator=/",n,o)).then(function(e){var t=[];return e.map(function(e){t.push(App.Key.create({Key:e}))}),t})})},setupController:function(e,t){var n=t.key,o=this.getParentAndGrandparent(n);t.keys=this.removeDuplicateKeys(t.keys,t.key),e.set("content",t.keys),e.set("parentKey",o.parent),e.set("grandParentKey",o.grandParent),e.set("isRoot",o.isRoot),e.set("newKey",App.Key.create()),e.set("rootKey",this.rootKey)}}),App.KvEditRoute=App.BaseRoute.extend({model:function(e){var t=e.key,n=this.modelFor("dc").dc,o=this.getParentAndGrandparent(t),r=App.get("settings.token");return Ember.RSVP.hash({dc:n,token:r,key:Ember.$.getJSON(formatUrl("/v1/kv/"+t,n,r)).then(function(e){return App.Key.create().setProperties(e[0])}),keys:keysPromise=Ember.$.getJSON(formatUrl("/v1/kv/"+o.parent+"?keys&seperator=/",n,r)).then(function(e){var t=[];return e.map(function(e){t.push(App.Key.create({Key:e}))}),t})})},afterModel:function(e){return e.key.get("isLocked")?Ember.$.getJSON(formatUrl("/v1/session/info/"+e.key.Session,e.dc,e.token)).then(function(t){return e.session=t[0],e}):e},setupController:function(e,t){var n=t.key,o=this.getParentAndGrandparent(n.get("Key"));t.keys=this.removeDuplicateKeys(t.keys,o.parent),e.set("content",t.key),e.set("parentKey",o.parent),e.set("grandParentKey",o.grandParent),e.set("isRoot",o.isRoot),e.set("siblings",t.keys),e.set("rootKey",this.rootKey),e.set("session",t.session)}}),App.ServicesRoute=App.BaseRoute.extend({model:function(){var e=this.modelFor("dc").dc,t=App.get("settings.token");return Ember.$.getJSON(formatUrl("/v1/internal/ui/services",e,t)).then(function(e){var t=[];return e.map(function(e){t.push(App.Service.create(e))}),t})},setupController:function(e,t){e.set("services",t)}}),App.ServicesShowRoute=App.BaseRoute.extend({model:function(e){var t=this.modelFor("dc").dc,n=App.get("settings.token");return Ember.$.getJSON(formatUrl("/v1/health/service/"+e.name,t,n)).then(function(e){var t=[];return e.map(function(e){t.push(App.Node.create(e))}),t})},setupController:function(e,t){var n=[];t.map(function(e){n=n.concat(e.Service.Tags)}),n=n.filter(function(e){return void 0!==e}),n=n.uniq().join(", "),e.set("content",t),e.set("tags",n)}}),App.NodesShowRoute=App.BaseRoute.extend({model:function(e){var t=this.modelFor("dc").dc,n=App.get("settings.token");return Ember.RSVP.hash({dc:t,token:n,node:Ember.$.getJSON(formatUrl("/v1/internal/ui/node/"+e.name,t,n)).then(function(e){return App.Node.create(e)}),nodes:Ember.$.getJSON(formatUrl("/v1/internal/ui/node/"+e.name,t,n)).then(function(e){return App.Node.create(e)})})},afterModel:function(e){return Ember.$.getJSON(formatUrl("/v1/session/node/"+e.node.Node,e.dc,e.token)).then(function(t){return e.sessions=t,e})},setupController:function(e,t){e.set("content",t.node),e.set("sessions",t.sessions),e.set("nodes",t.nodes)}}),App.NodesRoute=App.BaseRoute.extend({model:function(){var e=this.modelFor("dc").dc,t=App.get("settings.token");return Ember.$.getJSON(formatUrl("/v1/internal/ui/nodes",e,t)).then(function(e){var t=[];return e.map(function(e){t.push(App.Node.create(e))}),t})},setupController:function(e,t){e.set("nodes",t)}}),App.AclsRoute=App.BaseRoute.extend({model:function(){var e=this.modelFor("dc").dc,t=App.get("settings.token");return Ember.$.getJSON(formatUrl("/v1/acl/list",e,t)).then(function(e){var t=[];return e.map(function(e){"anonymous"===e.ID?t.unshift(App.Acl.create(e)):t.push(App.Acl.create(e))}),t})},actions:{error:function(e){return e&&401===e.status?this.transitionTo("dc.aclsdisabled"):e&&403===e.status&&this.transitionTo("dc.unauthorized"),!0}},setupController:function(e,t){e.set("acls",t),e.set("newAcl",App.Acl.create())}}),App.AclsShowRoute=App.BaseRoute.extend({model:function(e){var t=this.modelFor("dc").dc,n=App.get("settings.token");return Ember.RSVP.hash({dc:t,acl:Ember.$.getJSON(formatUrl("/v1/acl/info/"+e.id,t,n)).then(function(e){return App.Acl.create(e[0])})})},setupController:function(e,t){e.set("content",t.acl)}}),App.SettingsRoute=App.BaseRoute.extend({model:function(){return App.get("settings")}});App.ApplicationController=Ember.ObjectController.extend({updateCurrentPath:function(){App.set("currentPath",this.get("currentPath"))}.observes("currentPath")}),App.DcController=Ember.Controller.extend({needs:["application"],isDropdownVisible:!1,datacenter:Ember.computed.alias("content"),totalChecksFailing:function(){return this.get("nodes").reduce(function(e,t){return e+t.get("failingChecks")},0)}.property("nodes"),totalChecksPassing:function(){return this.get("nodes").reduce(function(e,t){return e+t.get("passingChecks")},0)}.property("nodes"),checkMessage:function(){var e=this.get("totalChecksFailing"),t=this.get("totalChecksPassing");return this.get("hasFailingChecks")===!0?e+" failing":t+" passing"}.property("nodes"),checkStatus:function(){return this.get("hasFailingChecks")===!0?"failing":"passing"}.property("nodes"),hasFailingChecks:Ember.computed.gt("totalChecksFailing",0),actions:{toggle:function(){this.toggleProperty("isDropdownVisible")},hideDrop:function(){this.set("isDropdownVisible",!1)}}}),KvBaseController=Ember.ObjectController.extend({getParentKeyRoute:function(){return this.get(this.get("isRoot")?"rootKey":"parentKey")},transitionToNearestParent:function(e){var t=this,n=t.get("rootKey"),s=t.get("dc").get("datacenter"),o=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/kv/"+e+"?keys",s,o),type:"GET"}).then(function(){t.transitionToRoute("kv.show",e)}).fail(function(e){404===e.status&&t.transitionToRoute("kv.show",n)}),t.set("isLoading",!1)}}),App.KvShowController=KvBaseController.extend(Ember.Validations.Mixin,{needs:["dc"],dc:Ember.computed.alias("controllers.dc"),isLoading:!1,actions:{createKey:function(){this.set("isLoading",!0);var e=this,t=e.get("newKey"),n=e.get("parentKey"),s=(e.get("grandParentKey"),e.get("dc").get("datacenter")),o=App.get("settings.token");void 0!==n&&"/"!==n&&t.set("Key",n+t.get("Key")),Ember.$.ajax({url:formatUrl("/v1/kv/"+t.get("Key"),s,o),type:"PUT",data:t.get("Value")}).then(function(){t.get("isFolder")===!0?e.transitionToRoute("kv.show",t.get("Key")):e.transitionToRoute("kv.edit",t.get("Key")),e.set("isLoading",!1)}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText)})},deleteFolder:function(){this.set("isLoading",!0);var e=this,t=e.get("dc").get("datacenter"),n=e.get("grandParentKey"),s=App.get("settings.token");window.confirm("Are you sure you want to delete this folder?")&&Ember.$.ajax({url:formatUrl("/v1/kv/"+e.get("parentKey")+"?recurse",t,s),type:"DELETE"}).then(function(){e.transitionToNearestParent(n)}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText)})}}}),App.KvEditController=KvBaseController.extend({isLoading:!1,needs:["dc"],dc:Ember.computed.alias("controllers.dc"),actions:{updateKey:function(){this.set("isLoading",!0);var e=this.get("dc").get("datacenter"),t=this.get("model"),n=this,s=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/kv/"+t.get("Key"),e,s),type:"PUT",data:t.get("valueDecoded")}).then(function(){n.set("isLoading",!1)}).fail(function(e){n.set("errorMessage","Received error while processing: "+e.statusText)})},cancelEdit:function(){this.set("isLoading",!0),this.transitionToRoute("kv.show",this.getParentKeyRoute()),this.set("isLoading",!1)},deleteKey:function(){this.set("isLoading",!0);var e=this,t=e.get("dc").get("datacenter"),n=e.get("model"),s=e.getParentKeyRoute(),o=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/kv/"+n.get("Key"),t,o),type:"DELETE"}).then(function(){e.transitionToNearestParent(s)}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText)})}}}),ItemBaseController=Ember.ArrayController.extend({needs:["dc","application"],queryParams:["filter","status","condensed"],dc:Ember.computed.alias("controllers.dc"),condensed:!0,hasExpanded:!0,filterText:"Filter by name",filter:"",status:"any status",statuses:["any status","passing","failing"],isShowingItem:function(){var e=this.get("controllers.application.currentPath");return"dc.nodes.show"===e||"dc.services.show"===e}.property("controllers.application.currentPath"),filteredContent:function(){var e=this.get("filter"),t=this.get("status"),n=this.get("items").filter(function(t){return t.get("filterKey").toLowerCase().match(e.toLowerCase())});switch(t){case"passing":return n.filterBy("hasFailingChecks",!1);case"failing":return n.filterBy("hasFailingChecks",!0);default:return n}}.property("filter","status","items.@each"),actions:{toggleCondensed:function(){this.toggleProperty("condensed")}}}),App.NodesShowController=Ember.ObjectController.extend({needs:["dc","nodes"],dc:Ember.computed.alias("controllers.dc"),actions:{deregisterNode:function(){this.set("isLoading",!0);var e=this,t=e.get("model"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");window.confirm("Are you sure you want to deregister this node?")&&Ember.$.ajax({url:formatUrl("/v1/catalog/deregister",n,s),type:"PUT",data:JSON.stringify({Datacenter:n,Node:t.Node})}).then(function(){var n=e.get("controllers.nodes").get("nodes");e.get("controllers.nodes").set("nodes",n.filter(function(e){return e.Node!==t.Node})),e.transitionToRoute("nodes")}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText)})},invalidateSession:function(e){this.set("isLoading",!0);var t=this,n=t.get("model"),s=t.get("dc").get("datacenter"),o=App.get("settings.token");window.confirm("Are you sure you want to invalidate this session?")&&Ember.$.ajax({url:formatUrl("/v1/session/destroy/"+e,s,o),type:"PUT"}).then(function(){return Ember.$.getJSON(formatUrl("/v1/session/node/"+n.Node,s,o)).then(function(e){t.set("sessions",e)})}).fail(function(e){t.set("errorMessage","Received error while processing: "+e.statusText)})}}}),App.NodesController=ItemBaseController.extend({items:Ember.computed.alias("nodes")}),App.ServicesController=ItemBaseController.extend({items:Ember.computed.alias("services")}),App.AclsController=Ember.ArrayController.extend({needs:["dc","application"],queryParams:["filter"],filterText:"Filter by name or ID",searchBar:!0,newAclButton:!0,types:["management","client"],dc:Ember.computed.alias("controllers.dc"),items:Ember.computed.alias("acls"),filter:"",isShowingItem:function(){var e=this.get("controllers.application.currentPath");return"dc.acls.show"===e}.property("controllers.application.currentPath"),filteredContent:function(){var e=this.get("filter"),t=this.get("items").filter(function(t){var n=t.get("Name").toLowerCase().match(e.toLowerCase());return null!==n?n:t.get("ID").toLowerCase().match(e.toLowerCase())});return t}.property("filter","items.@each"),actions:{createAcl:function(){this.set("isLoading",!0);var e=this,t=e.get("newAcl"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/acl/create",n,s),type:"PUT",data:JSON.stringify(t)}).then(function(t){e.transitionToRoute("acls.show",t.ID),Ember.$.getJSON(formatUrl("/v1/acl/list",n,s)).then(function(t){var n=[];t.map(function(e){n.push(App.Acl.create(e))}),e.set("items",n)}),e.set("isLoading",!1)}).fail(function(t){notify("Received error while creating ACL: "+t.statusText,8e3),e.set("isLoading",!1)})}}}),App.AclsShowController=Ember.ObjectController.extend({needs:["dc","acls"],dc:Ember.computed.alias("controllers.dc"),isLoading:!1,types:["management","client"],actions:{set:function(){this.set("isLoading",!0);{var e=this,t=e.get("model");e.get("dc").get("datacenter")}if(window.confirm("Are you sure you want to use this token for your session?")){{App.set("settings.token",t.ID)}e.transitionToRoute("services"),this.set("isLoading",!1),notify("Now using token: "+t.ID,3e3)}},clone:function(){this.set("isLoading",!0);var e=this,t=e.get("model"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");e.transitionToRoute("services"),Ember.$.ajax({url:formatUrl("/v1/acl/clone/"+t.ID,n,s),type:"PUT"}).then(function(t){e.transitionToRoute("acls.show",t.ID),e.set("isLoading",!1),notify("Successfully cloned token",4e3)}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText),e.set("isLoading",!1)})},"delete":function(){this.set("isLoading",!0);var e=this,t=e.get("model"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");window.confirm("Are you sure you want to delete this token?")&&Ember.$.ajax({url:formatUrl("/v1/acl/destroy/"+t.ID,n,s),type:"PUT"}).then(function(){Ember.$.getJSON(formatUrl("/v1/acl/list",n,s)).then(function(t){objs=[],t.map(function(e){"anonymous"===e.ID?objs.unshift(App.Acl.create(e)):objs.push(App.Acl.create(e))}),e.get("controllers.acls").set("acls",objs)}).then(function(){e.transitionToRoute("acls"),e.set("isLoading",!1),notify("ACL deleted successfully",3e3)})}).fail(function(t){e.set("errorMessage","Received error while processing: "+t.statusText),e.set("isLoading",!1)})},updateAcl:function(){this.set("isLoading",!0);var e=this,t=e.get("model"),n=e.get("dc").get("datacenter"),s=App.get("settings.token");Ember.$.ajax({url:formatUrl("/v1/acl/update",n,s),type:"PUT",data:JSON.stringify(t)}).then(function(){e.set("isLoading",!1),notify("ACL updated successfully",3e3)}).fail(function(t){notify("Received error while updating ACL: "+t.statusText,8e3),e.set("isLoading",!1)})}}}),App.SettingsController=Ember.ObjectController.extend({actions:{reset:function(){this.set("isLoading",!0);var e=this;window.confirm("Are your sure you want to reset your settings?")&&(localStorage.clear(),e.set("content",App.Settings.create()),App.set("settings.token",""),notify("Settings reset",3e3),this.set("isLoading",!1))}}});App.DcView=Ember.View.extend({templateName:"dc",classNames:"dropdowns",click:function(e){$(e.target).is(".dropdowns")&&$("ul.dropdown-menu").hide()}}),App.ItemView=Ember.View.extend({templateName:"item"}),App.ServicesView=Ember.View.extend({templateName:"services"}),App.ServicesShowView=Ember.View.extend({templateName:"service"}),App.ServicesLoadingView=Ember.View.extend({templateName:"item/loading"}),App.NodesView=Ember.View.extend({templateName:"nodes"}),App.NodesShowView=Ember.View.extend({templateName:"node"}),App.NodesLoadingView=Ember.View.extend({templateName:"item/loading"}),App.KvListView=Ember.View.extend({templateName:"kv"}),App.ActionBarView=Ember.View.extend({templateName:"actionbar"}),App.AclView=Ember.View.extend({templateName:"acls"}),App.AclsShowView=Ember.View.extend({templateName:"acl"}),App.SettingsView=Ember.View.extend({templateName:"settings"});function notify(e,a){void 0!==window.notifications&&window.notifications.length>0&&$(window.notifications).each(function(e,a){a.dismiss()});var n=new NotificationFx({message:"

"+e+"

",layout:"growl",effect:"slide",type:"notice",ttl:a});n.show(),window.notifications=[],window.notifications.push(n)}Ember.Handlebars.helper("panelBar",function(e){var a;return a="passing"==e?"bg-green":"bg-orange",new Handlebars.SafeString('
')}),Ember.Handlebars.helper("listBar",function(e){var a;return a="passing"==e?"bg-green":"bg-orange",new Handlebars.SafeString('
')}),Ember.Handlebars.helper("sessionName",function(e){var a;return a=""===e.Name?""+e.ID+"":""+e.Name+" "+e.ID+"",new Handlebars.SafeString(a)}),Ember.Handlebars.helper("sessionMeta",function(e){var a='";return""!==e.TTL&&(a=a+'"),new Handlebars.SafeString(a)}),Ember.Handlebars.helper("aclName",function(e,a){return""===e?a:new Handlebars.SafeString(e+' '+a+"")}),Ember.Handlebars.helper("formatRules",function(e){return""===e?"No rules defined":e}),Ember.Handlebars.helper("serviceTagMessage",function(e){return null===e?"No tags":void 0}); diff --git a/src/test/resources/consul_ui/static/base.css b/src/test/resources/consul_ui/static/base.css index 1598f156..dbb2ffe5 100644 --- a/src/test/resources/consul_ui/static/base.css +++ b/src/test/resources/consul_ui/static/base.css @@ -1,1004 +1,1354 @@ body { - -webkit-font-smoothing: antialiased; - font-size: 16px; - color: #555; } + -webkit-font-smoothing: antialiased; + font-size: 16px; + color: #555; +} a { - color: #9e84c5; - font-weight: 600; - -webkit-transition: color 0.2s ease-in-out; - -moz-transition: color 0.2s ease-in-out; - -ms-transition: color 0.2s ease-in-out; - -o-transition: color 0.2s ease-in-out; - transition: color 0.2s ease-in-out; } - a:hover { - text-decoration: none; - color: #8262b4; } - a.subtle { - color: inherit; } - a.subtle:hover { - color: #9e84c5; } + color: #9e84c5; + font-weight: 600; + -webkit-transition: color 0.2s ease-in-out; + -moz-transition: color 0.2s ease-in-out; + -ms-transition: color 0.2s ease-in-out; + -o-transition: color 0.2s ease-in-out; + transition: color 0.2s ease-in-out; +} + +a:hover { + text-decoration: none; + color: #8262b4; +} + +a.subtle { + color: inherit; +} + +a.subtle:hover { + color: #9e84c5; +} code { - color: #69499a; - background-color: #E6E6E6; } + color: #69499a; + background-color: #E6E6E6; +} .help-block { - font-size: 14px; - color: #939393; } + font-size: 14px; + color: #939393; +} small { - color: #777; } + color: #777; +} h1, h2, h3, h4, h5 { - color: #555; } + color: #555; +} h5 { - text-transform: uppercase; - font-weight: 700; - color: #939393; } + text-transform: uppercase; + font-weight: 700; + color: #939393; +} h4.breadcrumbs { - padding-bottom: 5px; - text-transform: uppercase; } - h4.breadcrumbs a { - color: #939393; } + padding-bottom: 5px; + text-transform: uppercase; +} + +h4.breadcrumbs a { + color: #939393; +} pre { - background-color: #777; - color: white; - font-weight: 700; - font-size: 12px; } + background-color: #777; + color: white; + font-weight: 700; + font-size: 12px; +} .bold { - font-weight: 700; } + font-weight: 700; +} .light { - color: #777; } + color: #777; +} .panel { - border-width: 2px; - border-color: #E6E6E6; - -webkit-transition: background-color 0.3s ease-in-out; - -moz-transition: background-color 0.3s ease-in-out; - -ms-transition: background-color 0.3s ease-in-out; - -o-transition: background-color 0.3s ease-in-out; - transition: background-color 0.3s ease-in-out; } - .panel .panel-heading { - padding: 10px 7px; - background-color: transparent; - border-width: 2px; - border-color: #E6E6E6; } - .panel h4.panel-title { - padding: 4px 10px 4px 2px; - font-size: 20px; - color: #939393; - color: #555; - border-radius: 3px; - opacity: 0.8; } - .panel h4.panel-title small { - font-size: 14px; - text-transform: uppercase; - font-weight: 700; - margin-left: 5px; - padding-top: 2px; } - .panel h4.panel-title .no-case { - text-transform: none; } - .panel h4.panel-title .panel-note { - margin-top: 5px; - float: right; - font-weight: 600; - color: #939393; - font-size: 14px; } - .panel h3.panel-title { - padding: 4px 0px 4px 0px; - font-size: 20px; - color: #939393; - color: #555; - border-radius: 3px; } - .panel h3.panel-title small { - font-size: 14px; - margin-left: 5px; } - .panel h3.panel-title .panel-note { - margin-top: 5px; - float: right; - font-weight: 600; - color: #939393; - font-size: 14px; } - .panel .panel-body { - padding: 0px 7px 0px 7px; } - .panel .panel-body p { - font-size: 14px; - color: #555; } - .panel .panel-body h5 { - font-size: 12px; } - .panel .panel-body h4.check { - font-size: 16px; } - .panel .panel-body.panel-form { - padding-bottom: 15px; } - .panel .panel-bar { - width: 100%; - height: 20px; - -webkit-transition: background-color 0.1s linear; - -moz-transition: background-color 0.1s linear; - -ms-transition: background-color 0.1s linear; - -o-transition: background-color 0.1s linear; - transition: background-color 0.1s linear; } - .panel.panel-link { - border-bottom-width: 2px; } - .panel.panel-list ul { - margin: 0; } - .panel.panel-list ul li { - margin: 0; - border: 0; } - .panel .panel-bar-horizontal { - width: 20px; - float: left; - height: 50px; - margin-right: 10px; - display: block; } - .panel.panel-short { - border-bottom-width: 0px; } - .panel.panel-link:hover { - cursor: pointer; - background-color: #fafafa; } - .panel.active { - -webkit-transition: border-color 0.1s linear; - -moz-transition: border-color 0.1s linear; - -ms-transition: border-color 0.1s linear; - -o-transition: border-color 0.1s linear; - transition: border-color 0.1s linear; - border-color: #9e84c5; } - .panel.active > .panel-heading { - border-color: #9e84c5; } - .panel.active .panel-bar { - -webkit-transition: background-color 0.1s linear; - -moz-transition: background-color 0.1s linear; - -ms-transition: background-color 0.1s linear; - -o-transition: background-color 0.1s linear; - transition: background-color 0.1s linear; - background-color: #9e84c5; } + border-width: 2px; + border-color: #E6E6E6; + -webkit-transition: background-color 0.3s ease-in-out; + -moz-transition: background-color 0.3s ease-in-out; + -ms-transition: background-color 0.3s ease-in-out; + -o-transition: background-color 0.3s ease-in-out; + transition: background-color 0.3s ease-in-out; +} + +.panel .panel-heading { + padding: 10px 7px; + background-color: transparent; + border-width: 2px; + border-color: #E6E6E6; +} + +.panel h4.panel-title { + padding: 4px 10px 4px 2px; + font-size: 20px; + color: #939393; + color: #555; + border-radius: 3px; + opacity: 0.8; +} + +.panel h4.panel-title small { + font-size: 14px; + text-transform: uppercase; + font-weight: 700; + margin-left: 5px; + padding-top: 2px; +} + +.panel h4.panel-title .no-case { + text-transform: none; +} + +.panel h4.panel-title .panel-note { + margin-top: 5px; + float: right; + font-weight: 600; + color: #939393; + font-size: 14px; +} + +.panel h3.panel-title { + padding: 4px 0px 4px 0px; + font-size: 20px; + color: #939393; + color: #555; + border-radius: 3px; +} + +.panel h3.panel-title small { + font-size: 14px; + margin-left: 5px; +} + +.panel h3.panel-title .panel-note { + margin-top: 5px; + float: right; + font-weight: 600; + color: #939393; + font-size: 14px; +} + +.panel .panel-body { + padding: 0px 7px 0px 7px; +} + +.panel .panel-body p { + font-size: 14px; + color: #555; +} + +.panel .panel-body h5 { + font-size: 12px; +} + +.panel .panel-body h4.check { + font-size: 16px; +} + +.panel .panel-body.panel-form { + padding-bottom: 15px; +} + +.panel .panel-bar { + width: 100%; + height: 20px; + -webkit-transition: background-color 0.1s linear; + -moz-transition: background-color 0.1s linear; + -ms-transition: background-color 0.1s linear; + -o-transition: background-color 0.1s linear; + transition: background-color 0.1s linear; +} + +.panel.panel-link { + border-bottom-width: 2px; +} + +.panel.panel-list ul { + margin: 0; +} + +.panel.panel-list ul li { + margin: 0; + border: 0; +} + +.panel .panel-bar-horizontal { + width: 20px; + float: left; + height: 50px; + margin-right: 10px; + display: block; +} + +.panel.panel-short { + border-bottom-width: 0px; +} + +.panel.panel-link:hover { + cursor: pointer; + background-color: #fafafa; +} + +.panel.active { + -webkit-transition: border-color 0.1s linear; + -moz-transition: border-color 0.1s linear; + -ms-transition: border-color 0.1s linear; + -o-transition: border-color 0.1s linear; + transition: border-color 0.1s linear; + border-color: #9e84c5; +} + +.panel.active > .panel-heading { + border-color: #9e84c5; +} + +.panel.active .panel-bar { + -webkit-transition: background-color 0.1s linear; + -moz-transition: background-color 0.1s linear; + -ms-transition: background-color 0.1s linear; + -o-transition: background-color 0.1s linear; + transition: background-color 0.1s linear; + background-color: #9e84c5; +} .top-brand { - margin-top: 20px; - background: transparent url("consul-logo.png") 0 no-repeat; - background-size: 30px 30px; - width: 30px; - height: 30px; } + margin-top: 20px; + background: transparent url("consul-logo.png") 0 no-repeat; + background-size: 30px 30px; + width: 30px; + height: 30px; +} .topbar { - padding: 30px; - padding-top: 10px; - padding-bottom: 10px; - margin-bottom: 20px; - min-height: 95px; - border-bottom: 1px #eee solid; } - .topbar .btn { - margin-top: 20px; - min-width: 100px; } - .topbar .btn-dropdown { - width: auto; } - .topbar ul.dropdown-menu li a { - text-transform: uppercase; - font-weight: 600; - font-size: 12px; - color: #777; - -webkit-transition: background-color 0.1s ease-in-out; - -moz-transition: background-color 0.1s ease-in-out; - -ms-transition: background-color 0.1s ease-in-out; - -o-transition: background-color 0.1s ease-in-out; - transition: background-color 0.1s ease-in-out; } - .topbar ul.dropdown-menu li a:hover { - color: #5e5e5e; - background-color: #f3f3f3; } + padding: 30px; + padding-top: 10px; + padding-bottom: 10px; + margin-bottom: 20px; + min-height: 95px; + border-bottom: 1px #eee solid; +} + +.topbar .btn { + margin-top: 20px; + min-width: 100px; +} + +.topbar .btn-dropdown { + width: auto; +} + +.topbar ul.dropdown-menu li a { + text-transform: uppercase; + font-weight: 600; + font-size: 12px; + color: #777; + -webkit-transition: background-color 0.1s ease-in-out; + -moz-transition: background-color 0.1s ease-in-out; + -ms-transition: background-color 0.1s ease-in-out; + -o-transition: background-color 0.1s ease-in-out; + transition: background-color 0.1s ease-in-out; +} + +.topbar ul.dropdown-menu li a:hover { + color: #5e5e5e; + background-color: #f3f3f3; +} .btn { - text-transform: uppercase; - font-weight: 600; - font-size: 12px; - border-width: 2px; - color: #777; - -webkit-transition: background-color 0.2s ease-in-out; - -moz-transition: background-color 0.2s ease-in-out; - -ms-transition: background-color 0.2s ease-in-out; - -o-transition: background-color 0.2s ease-in-out; - transition: background-color 0.2s ease-in-out; - -webkit-transition: border-color 0.2s ease-in-out; - -moz-transition: border-color 0.2s ease-in-out; - -ms-transition: border-color 0.2s ease-in-out; - -o-transition: border-color 0.2s ease-in-out; - transition: border-color 0.2s ease-in-out; - -webkit-transition: color 0.2s ease-in-out; - -moz-transition: color 0.2s ease-in-out; - -ms-transition: color 0.2s ease-in-out; - -o-transition: color 0.2s ease-in-out; - transition: color 0.2s ease-in-out; - outline: none; - outline-color: white; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; } - .btn:hover { - color: #5e5e5e; - background-color: #f3f3f3; } - .btn:focus { - outline: none; - outline-color: white; - outline: none; - box-shadow: none; } - .btn.active { - outline-color: white; - outline: none; - box-shadow: none; } - .btn.btn-primary { - color: #69499a; - background-color: transparent; - border: 2px solid #9e84c5; } - .btn.btn-primary:hover { - background-color: #f7f3f9; - color: #8262b4; } - .btn.btn-warning { - color: #FFAC5E; - background-color: transparent; - border: 2px solid #FFAC5E; } - .btn.btn-warning:hover { - background-color: #fff8f2; - color: #ff922b; } - .btn.btn-success { - color: #86B457; - background-color: transparent; - border: 2px solid #86B457; } - .btn.btn-success:hover { - background-color: #f8fdf2; - color: #6c9543; } - .btn.btn-danger { - color: #dd4e58; - background-color: transparent; - border: 2px solid #dd4e58; } - .btn.btn-danger:hover { - background-color: #fcf1f1; - color: #d02834; } - .btn.active { - color: #69499a; - background-color: transparent; - border: 2px solid #9e84c5; } - .btn.active:hover { - background-color: #f7f3f9; - color: #8262b4; } - .btn.active.btn-noactive { - color: inherit; - background-color: inherit; - border: 2px solid #ccc; } - .btn.btn-mini { - font-size: 10px; - padding: 8px; } - .btn.btn-list { - font-size: 10px; - padding: 3px 5px 3px 5px; - margin-right: 5px; - border-radius: 3px; } + text-transform: uppercase; + font-weight: 600; + font-size: 12px; + border-width: 2px; + color: #777; + -webkit-transition: background-color 0.2s ease-in-out; + -moz-transition: background-color 0.2s ease-in-out; + -ms-transition: background-color 0.2s ease-in-out; + -o-transition: background-color 0.2s ease-in-out; + transition: background-color 0.2s ease-in-out; + -webkit-transition: border-color 0.2s ease-in-out; + -moz-transition: border-color 0.2s ease-in-out; + -ms-transition: border-color 0.2s ease-in-out; + -o-transition: border-color 0.2s ease-in-out; + transition: border-color 0.2s ease-in-out; + -webkit-transition: color 0.2s ease-in-out; + -moz-transition: color 0.2s ease-in-out; + -ms-transition: color 0.2s ease-in-out; + -o-transition: color 0.2s ease-in-out; + transition: color 0.2s ease-in-out; + outline: none; + outline-color: white; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.btn:hover { + color: #5e5e5e; + background-color: #f3f3f3; +} + +.btn:focus { + outline: none; + outline-color: white; + outline: none; + box-shadow: none; +} + +.btn.active { + outline-color: white; + outline: none; + box-shadow: none; +} + +.btn.btn-primary { + color: #69499a; + background-color: transparent; + border: 2px solid #9e84c5; +} + +.btn.btn-primary:hover { + background-color: #f7f3f9; + color: #8262b4; +} + +.btn.btn-warning { + color: #FFAC5E; + background-color: transparent; + border: 2px solid #FFAC5E; +} + +.btn.btn-warning:hover { + background-color: #fff8f2; + color: #ff922b; +} + +.btn.btn-success { + color: #86B457; + background-color: transparent; + border: 2px solid #86B457; +} + +.btn.btn-success:hover { + background-color: #f8fdf2; + color: #6c9543; +} + +.btn.btn-danger { + color: #dd4e58; + background-color: transparent; + border: 2px solid #dd4e58; +} + +.btn.btn-danger:hover { + background-color: #fcf1f1; + color: #d02834; +} + +.btn.active { + color: #69499a; + background-color: transparent; + border: 2px solid #9e84c5; +} + +.btn.active:hover { + background-color: #f7f3f9; + color: #8262b4; +} + +.btn.active.btn-noactive { + color: inherit; + background-color: inherit; + border: 2px solid #ccc; +} + +.btn.btn-mini { + font-size: 10px; + padding: 8px; +} + +.btn.btn-list { + font-size: 10px; + padding: 3px 5px 3px 5px; + margin-right: 5px; + border-radius: 3px; +} .topbar .btn.icon { - min-width: 50px; - height: 33px; - padding: 6px 0; } - .topbar .btn.icon svg { - height: 20px; - fill: currentColor; } + min-width: 50px; + height: 33px; + padding: 6px 0; +} + +.topbar .btn.icon svg { + height: 20px; + fill: currentColor; +} .list-group-item { - padding: 0; - border-width: 2px; - border-bottom-width: 2px; - border-radius: 2px; - margin-bottom: 15px; - margin-top: 15px; - -webkit-transition: background-color 0.3s ease-in-out; - -moz-transition: background-color 0.3s ease-in-out; - -ms-transition: background-color 0.3s ease-in-out; - -o-transition: background-color 0.3s ease-in-out; - transition: background-color 0.3s ease-in-out; } - .list-group-item .list-group-item-heading, .list-group-item .list-inline { - margin: 10px 15px 10px 15px; - padding: 0px 5px 0px 5px; } - .list-group-item .list-inline { - padding-left: 0px; - color: #777; - font-size: 13px; - height: 20px; } - .list-group-item .list-group-item-heading { - border-bottom: 2px solid #eee; - color: #555; } - .list-group-item .list-group-item-heading .heading-helper { - float: right; - font-weight: 600; - color: #939393; - font-size: 14px; } - .list-group-item .list-bar { - width: 100%; - height: 20px; } - .list-group-item.list-link:hover { - cursor: pointer; - background-color: #fafafa; } - .list-group-item.list-condensed-link:hover { - cursor: pointer; - background-color: #fafafa; } - .list-group-item.list-condensed-link, .list-group-item.list-condensed { - border-color: #E6E6E6; - margin-bottom: 4px; - margin-top: 4px; - height: 40px; - font-weight: 700; } - .list-group-item.list-condensed-link.double-line, .list-group-item.list-condensed.double-line { - height: 54px; } - .list-group-item.list-condensed-link .name, .list-group-item.list-condensed .name { - font-size: 15px; - padding-top: 6px; } - .list-group-item.list-condensed-link .name span, .list-group-item.list-condensed .name span { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 35%; - float: left; - display: inline-block; - padding-right: 4px; } - .list-group-item.list-condensed-link .name small, .list-group-item.list-condensed .name small { - display: inline-block; - padding-right: 8px; - padding-top: 2px; - font-size: 12px; - color: #939393; } - .list-group-item.list-condensed-link .metadata, .list-group-item.list-condensed .metadata { - display: block; - font-size: 12px; - float: left; - color: #939393; } - .list-group-item.list-condensed-link ul.sub, .list-group-item.list-condensed ul.sub { - margin: 0; - font-size: 12px; - color: #939393; - overflow: auto; } - .list-group-item.list-condensed-link ul.sub li, .list-group-item.list-condensed ul.sub li { - padding: 0; } - .list-group-item.list-condensed-link ul.sub::-webkit-scrollbar, .list-group-item.list-condensed ul.sub::-webkit-scrollbar { - display: none; - -webkit-appearance: none; } - .list-group-item .list-bar-horizontal { - width: 20px; - float: left; - height: 100%; - margin-right: 10px; } - .list-group-item.active { - -webkit-transition: border-color 0.1s linear; - -moz-transition: border-color 0.1s linear; - -ms-transition: border-color 0.1s linear; - -o-transition: border-color 0.1s linear; - transition: border-color 0.1s linear; - border-color: #9e84c5; } - .list-group-item.active .list-bar, .list-group-item.active .list-bar-horizontal { - -webkit-transition: background-color 0.1s linear; - -moz-transition: background-color 0.1s linear; - -ms-transition: background-color 0.1s linear; - -o-transition: background-color 0.1s linear; - transition: background-color 0.1s linear; - background-color: #9e84c5; } + padding: 0; + border-width: 2px; + border-bottom-width: 2px; + border-radius: 2px; + margin-bottom: 15px; + margin-top: 15px; + -webkit-transition: background-color 0.3s ease-in-out; + -moz-transition: background-color 0.3s ease-in-out; + -ms-transition: background-color 0.3s ease-in-out; + -o-transition: background-color 0.3s ease-in-out; + transition: background-color 0.3s ease-in-out; +} + +.list-group-item .list-group-item-heading, .list-group-item .list-inline { + margin: 10px 15px 10px 15px; + padding: 0px 5px 0px 5px; +} + +.list-group-item .list-inline { + padding-left: 0px; + color: #777; + font-size: 13px; + height: 20px; +} + +.list-group-item .list-group-item-heading { + border-bottom: 2px solid #eee; + color: #555; +} + +.list-group-item .list-group-item-heading .heading-helper { + float: right; + font-weight: 600; + color: #939393; + font-size: 14px; +} + +.list-group-item .list-bar { + width: 100%; + height: 20px; +} + +.list-group-item.list-link:hover { + cursor: pointer; + background-color: #fafafa; +} + +.list-group-item.list-condensed-link:hover { + cursor: pointer; + background-color: #fafafa; +} + +.list-group-item.list-condensed-link, .list-group-item.list-condensed { + border-color: #E6E6E6; + margin-bottom: 4px; + margin-top: 4px; + height: 40px; + font-weight: 700; +} + +.list-group-item.list-condensed-link.double-line, .list-group-item.list-condensed.double-line { + height: 54px; +} + +.list-group-item.list-condensed-link .name, .list-group-item.list-condensed .name { + font-size: 15px; + padding-top: 6px; +} + +.list-group-item.list-condensed-link .name span, .list-group-item.list-condensed .name span { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 35%; + float: left; + display: inline-block; + padding-right: 4px; +} + +.list-group-item.list-condensed-link .name small, .list-group-item.list-condensed .name small { + display: inline-block; + padding-right: 8px; + padding-top: 2px; + font-size: 12px; + color: #939393; +} + +.list-group-item.list-condensed-link .metadata, .list-group-item.list-condensed .metadata { + display: block; + font-size: 12px; + float: left; + color: #939393; +} + +.list-group-item.list-condensed-link ul.sub, .list-group-item.list-condensed ul.sub { + margin: 0; + font-size: 12px; + color: #939393; + overflow: auto; +} + +.list-group-item.list-condensed-link ul.sub li, .list-group-item.list-condensed ul.sub li { + padding: 0; +} + +.list-group-item.list-condensed-link ul.sub::-webkit-scrollbar, .list-group-item.list-condensed ul.sub::-webkit-scrollbar { + display: none; + -webkit-appearance: none; +} + +.list-group-item .list-bar-horizontal { + width: 20px; + float: left; + height: 100%; + margin-right: 10px; +} + +.list-group-item.active { + -webkit-transition: border-color 0.1s linear; + -moz-transition: border-color 0.1s linear; + -ms-transition: border-color 0.1s linear; + -o-transition: border-color 0.1s linear; + transition: border-color 0.1s linear; + border-color: #9e84c5; +} + +.list-group-item.active .list-bar, .list-group-item.active .list-bar-horizontal { + -webkit-transition: background-color 0.1s linear; + -moz-transition: background-color 0.1s linear; + -ms-transition: background-color 0.1s linear; + -o-transition: background-color 0.1s linear; + transition: background-color 0.1s linear; + background-color: #9e84c5; +} .form-group .form-control { - -webkit-transition: border-color 0.2s ease-in-out; - -moz-transition: border-color 0.2s ease-in-out; - -ms-transition: border-color 0.2s ease-in-out; - -o-transition: border-color 0.2s ease-in-out; - transition: border-color 0.2s ease-in-out; - -webkit-transition: box-shadow 0.2s ease-in-out; - -moz-transition: box-shadow 0.2s ease-in-out; - -ms-transition: box-shadow 0.2s ease-in-out; - -o-transition: box-shadow 0.2s ease-in-out; - transition: box-shadow 0.2s ease-in-out; - -webkit-transition: border-color 0.2s ease-in-out; - -moz-transition: border-color 0.2s ease-in-out; - -ms-transition: border-color 0.2s ease-in-out; - -o-transition: border-color 0.2s ease-in-out; - transition: border-color 0.2s ease-in-out; } - .form-group .form-control.form-control-mini { - font-size: 12px; } + -webkit-transition: border-color 0.2s ease-in-out; + -moz-transition: border-color 0.2s ease-in-out; + -ms-transition: border-color 0.2s ease-in-out; + -o-transition: border-color 0.2s ease-in-out; + transition: border-color 0.2s ease-in-out; + -webkit-transition: box-shadow 0.2s ease-in-out; + -moz-transition: box-shadow 0.2s ease-in-out; + -ms-transition: box-shadow 0.2s ease-in-out; + -o-transition: box-shadow 0.2s ease-in-out; + transition: box-shadow 0.2s ease-in-out; + -webkit-transition: border-color 0.2s ease-in-out; + -moz-transition: border-color 0.2s ease-in-out; + -ms-transition: border-color 0.2s ease-in-out; + -o-transition: border-color 0.2s ease-in-out; + transition: border-color 0.2s ease-in-out; +} + +.form-group .form-control.form-control-mini { + font-size: 12px; +} + .form-group.valid .form-control { - border-color: #BBF085; - box-shadow: 0 0 5px #BBF085; } + border-color: #BBF085; + box-shadow: 0 0 5px #BBF085; +} + .form-group .input-group-addon { - background-color: #E6E6E6; } + background-color: #E6E6E6; +} textarea.form-control { - height: 130px; } + height: 130px; +} .ns-box { - position: fixed; - background: #666666; - padding: 20px; - line-height: 1.4; - z-index: 1000; - min-width: 400px; - pointer-events: none; - color: rgba(250, 251, 255, 0.95); - font-weight: 700; - font-size: 15px; - opacity: 0.8; } + position: fixed; + background: #666666; + padding: 20px; + line-height: 1.4; + z-index: 1000; + min-width: 400px; + pointer-events: none; + color: rgba(250, 251, 255, 0.95); + font-weight: 700; + font-size: 15px; + opacity: 0.8; +} .ns-box.ns-show { - pointer-events: auto; } + pointer-events: auto; +} .ns-box a { - color: inherit; - opacity: 0.7; - font-weight: 700; } + color: inherit; + opacity: 0.7; + font-weight: 700; +} .ns-box a:hover, .ns-box a:focus { - opacity: 1; } + opacity: 1; +} .ns-box p { - margin: 0; } + margin: 0; +} .ns-box.ns-show, .ns-box.ns-visible { - pointer-events: auto; } + pointer-events: auto; +} .ns-close { - width: 20px; - height: 20px; - position: absolute; - right: 4px; - top: 4px; - overflow: hidden; - text-indent: 100%; - cursor: pointer; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; } + width: 20px; + height: 20px; + position: absolute; + right: 4px; + top: 4px; + overflow: hidden; + text-indent: 100%; + cursor: pointer; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} .ns-close:hover, .ns-close:focus { - outline: none; } + outline: none; +} .ns-close::before, .ns-close::after { - content: ''; - position: absolute; - width: 3px; - height: 60%; - top: 50%; - left: 50%; - background: white; } + content: ''; + position: absolute; + width: 3px; + height: 60%; + top: 50%; + left: 50%; + background: white; +} .ns-close:hover::before, .ns-close:hover::after { - background: #fff; } + background: #fff; +} .ns-close::before { - -webkit-transform: translate(-50%, -50%) rotate(45deg); - transform: translate(-50%, -50%) rotate(45deg); } + -webkit-transform: translate(-50%, -50%) rotate(45deg); + transform: translate(-50%, -50%) rotate(45deg); +} .ns-close::after { - -webkit-transform: translate(-50%, -50%) rotate(-45deg); - transform: translate(-50%, -50%) rotate(-45deg); } + -webkit-transform: translate(-50%, -50%) rotate(-45deg); + transform: translate(-50%, -50%) rotate(-45deg); +} /* Growl-style notifications */ .ns-growl { - top: 30px; - left: 30px; - max-width: 300px; - border-radius: 5px; } + top: 30px; + left: 30px; + max-width: 300px; + border-radius: 5px; +} .ns-growl p { - margin: 0; - line-height: 1.3; } + margin: 0; + line-height: 1.3; +} [class^="ns-effect-"].ns-growl.ns-hide, [class*=" ns-effect-"].ns-growl.ns-hide { - -webkit-animation-direction: reverse; - animation-direction: reverse; } + -webkit-animation-direction: reverse; + animation-direction: reverse; +} /* Slide */ .ns-effect-slide { - top: 30px; } + top: 30px; +} .ns-effect-slide .ns-close:hover::before, .ns-effect-slide .ns-close:hover::after { - background: #fff; } + background: #fff; +} .ns-effect-slide.ns-show { - -webkit-animation-name: animSlideElastic; - animation-name: animSlideElastic; - -webkit-animation-duration: 1s; - animation-duration: 1s; - -webkit-animation-timing-function: linear; - animation-timing-function: linear; } + -webkit-animation-name: animSlideElastic; + animation-name: animSlideElastic; + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-timing-function: linear; + animation-timing-function: linear; +} @-webkit-keyframes animSlideElastic { - 0% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); } - 1.666667% { - -webkit-transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); - transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); } - 3.333333% { - -webkit-transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); - transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); } - 5% { - -webkit-transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); - transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); } - 6.666667% { - -webkit-transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); - transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); } - 8.333333% { - -webkit-transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); - transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); } - 10% { - -webkit-transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); - transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); } - 11.666667% { - -webkit-transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); - transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); } - 13.333333% { - -webkit-transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); - transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); } - 15% { - -webkit-transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); - transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); } - 16.666667% { - -webkit-transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); - transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); } - 18.333333% { - -webkit-transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); - transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); } - 20% { - -webkit-transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); - transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); } - 21.666667% { - -webkit-transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); - transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); } - 23.333333% { - -webkit-transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); - transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); } - 25% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); } - 26.666667% { - -webkit-transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); - transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); } - 28.333333% { - -webkit-transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); - transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); } - 30% { - -webkit-transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); - transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); } - 31.666667% { - -webkit-transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); - transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); } - 33.333333% { - -webkit-transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); - transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); } - 35% { - -webkit-transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); - transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); } - 36.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); } - 38.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); } - 40% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); } - 41.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); } - 43.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); } - 45% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); } - 46.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); } - 48.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); } - 50% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); } - 51.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); } - 53.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); } - 55% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); } - 56.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); } - 58.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); } - 60% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); } - 61.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); } - 63.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); } - 65% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); } - 66.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); } - 68.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); } - 70% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); } - 71.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); } - 73.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); } - 75% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); } - 76.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); } - 78.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); } - 80% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); } - 81.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); } - 83.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); } - 85% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); } - 86.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); } - 88.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); } - 90% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); } - 91.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } - 93.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } - 95% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); } - 96.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); } - 98.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } } + 0% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); + } + 1.666667% { + -webkit-transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); + transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); + } + 3.333333% { + -webkit-transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); + transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); + } + 5% { + -webkit-transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); + transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); + } + 6.666667% { + -webkit-transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); + transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); + } + 8.333333% { + -webkit-transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); + transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); + } + 10% { + -webkit-transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); + transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); + } + 11.666667% { + -webkit-transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); + transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); + } + 13.333333% { + -webkit-transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); + transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); + } + 15% { + -webkit-transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); + transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); + } + 16.666667% { + -webkit-transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); + transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); + } + 18.333333% { + -webkit-transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); + transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); + } + 20% { + -webkit-transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); + transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); + } + 21.666667% { + -webkit-transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); + transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); + } + 23.333333% { + -webkit-transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); + transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); + } + 25% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); + } + 26.666667% { + -webkit-transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); + transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); + } + 28.333333% { + -webkit-transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); + transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); + } + 30% { + -webkit-transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); + transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); + } + 31.666667% { + -webkit-transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); + transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); + } + 33.333333% { + -webkit-transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); + transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); + } + 35% { + -webkit-transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); + transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); + } + 36.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); + } + 38.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); + } + 40% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); + } + 41.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); + } + 43.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); + } + 45% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); + } + 46.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); + } + 48.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); + } + 50% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); + } + 51.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); + } + 53.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); + } + 55% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); + } + 56.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); + } + 58.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); + } + 60% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); + } + 61.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); + } + 63.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); + } + 65% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); + } + 66.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); + } + 68.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); + } + 70% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); + } + 71.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); + } + 73.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); + } + 75% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); + } + 76.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); + } + 78.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); + } + 80% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); + } + 81.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); + } + 83.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); + } + 85% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); + } + 86.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); + } + 88.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); + } + 90% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + } + 91.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); + } + 93.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); + } + 95% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); + } + 96.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + } + 98.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); + } + 100% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } +} + @keyframes animSlideElastic { - 0% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); } - 1.666667% { - -webkit-transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); - transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); } - 3.333333% { - -webkit-transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); - transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); } - 5% { - -webkit-transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); - transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); } - 6.666667% { - -webkit-transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); - transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); } - 8.333333% { - -webkit-transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); - transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); } - 10% { - -webkit-transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); - transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); } - 11.666667% { - -webkit-transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); - transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); } - 13.333333% { - -webkit-transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); - transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); } - 15% { - -webkit-transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); - transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); } - 16.666667% { - -webkit-transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); - transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); } - 18.333333% { - -webkit-transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); - transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); } - 20% { - -webkit-transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); - transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); } - 21.666667% { - -webkit-transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); - transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); } - 23.333333% { - -webkit-transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); - transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); } - 25% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); } - 26.666667% { - -webkit-transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); - transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); } - 28.333333% { - -webkit-transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); - transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); } - 30% { - -webkit-transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); - transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); } - 31.666667% { - -webkit-transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); - transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); } - 33.333333% { - -webkit-transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); - transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); } - 35% { - -webkit-transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); - transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); } - 36.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); } - 38.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); } - 40% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); } - 41.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); } - 43.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); } - 45% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); } - 46.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); } - 48.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); } - 50% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); } - 51.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); } - 53.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); } - 55% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); } - 56.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); } - 58.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); } - 60% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); } - 61.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); } - 63.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); } - 65% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); } - 66.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); } - 68.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); } - 70% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); } - 71.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); } - 73.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); } - 75% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); } - 76.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); } - 78.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); } - 80% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); } - 81.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); } - 83.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); } - 85% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); } - 86.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); } - 88.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); } - 90% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); } - 91.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } - 93.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } - 95% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); } - 96.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); } - 98.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } } + 0% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); + } + 1.666667% { + -webkit-transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); + transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); + } + 3.333333% { + -webkit-transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); + transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); + } + 5% { + -webkit-transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); + transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); + } + 6.666667% { + -webkit-transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); + transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); + } + 8.333333% { + -webkit-transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); + transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); + } + 10% { + -webkit-transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); + transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); + } + 11.666667% { + -webkit-transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); + transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); + } + 13.333333% { + -webkit-transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); + transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); + } + 15% { + -webkit-transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); + transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); + } + 16.666667% { + -webkit-transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); + transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); + } + 18.333333% { + -webkit-transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); + transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); + } + 20% { + -webkit-transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); + transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); + } + 21.666667% { + -webkit-transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); + transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); + } + 23.333333% { + -webkit-transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); + transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); + } + 25% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); + } + 26.666667% { + -webkit-transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); + transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); + } + 28.333333% { + -webkit-transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); + transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); + } + 30% { + -webkit-transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); + transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); + } + 31.666667% { + -webkit-transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); + transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); + } + 33.333333% { + -webkit-transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); + transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); + } + 35% { + -webkit-transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); + transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); + } + 36.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); + } + 38.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); + } + 40% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); + } + 41.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); + } + 43.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); + } + 45% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); + } + 46.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); + } + 48.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); + } + 50% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); + } + 51.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); + } + 53.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); + } + 55% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); + } + 56.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); + } + 58.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); + } + 60% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); + } + 61.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); + } + 63.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); + } + 65% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); + } + 66.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); + } + 68.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); + } + 70% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); + } + 71.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); + } + 73.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); + } + 75% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); + } + 76.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); + } + 78.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); + } + 80% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); + } + 81.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); + } + 83.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); + } + 85% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); + } + 86.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); + } + 88.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); + } + 90% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + } + 91.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); + } + 93.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); + } + 95% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); + } + 96.666667% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + } + 98.333333% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); + } + 100% { + -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } +} + .ns-effect-slide.ns-hide { - -webkit-animation-name: animSlide; - animation-name: animSlide; - -webkit-animation-duration: 0.25s; - animation-duration: 0.25s; } + -webkit-animation-name: animSlide; + animation-name: animSlide; + -webkit-animation-duration: 0.25s; + animation-duration: 0.25s; +} @-webkit-keyframes animSlide { - 0% { - -webkit-transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); } - 100% { - -webkit-transform: translate3d(0, 0, 0); } } + 0% { + -webkit-transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + } +} + @keyframes animSlide { - 0% { - -webkit-transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); - transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); } - 100% { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); } } + 0% { + -webkit-transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); + transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); + } + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + html, body { - height: 100%; } + height: 100%; +} .wrapper { - min-height: 100%; - height: auto !important; - /* This line and the next line are not necessary unless you need IE6 support */ - height: 100%; - margin: 0 auto -60px; - /* the bottom margin is the negative value of the footer's height */ } + min-height: 100%; + height: auto !important; + /* This line and the next line are not necessary unless you need IE6 support */ + height: 100%; + margin: 0 auto -60px; + /* the bottom margin is the negative value of the footer's height */ +} .footer, .push { - height: 60px; - /* .push must be the same height as .footer */ } + height: 60px; + /* .push must be the same height as .footer */ +} @media (min-width: 1120px) { - .container { - width: 1100px; } } + .container { + width: 1100px; + } +} + @media (min-width: 1200px) { - .container { - width: 1200px; } } + .container { + width: 1200px; + } +} + @media (min-width: 1438px) { - .container { - width: 1400px; } } + .container { + width: 1400px; + } +} + a button:active { - outline: none; } + outline: none; +} .buffer-small { - height: 50px; } + height: 50px; +} @media (min-width: 991px) { - .border-left { - border-left: 1px #E6E6E6 solid; } - .border-left .padded-border { - padding-left: 30px; } } + .border-left { + border-left: 1px #E6E6E6 solid; + } + + .border-left .padded-border { + padding-left: 30px; + } +} + .padded-right-middle { - padding-right: 30px; } + padding-right: 30px; +} .no-margin { - margin: 0; } + margin: 0; +} .vertical-center { - margin-top: 200px; } + margin-top: 200px; +} .row.colored { - background-color: #f7f3f9; } + background-color: #f7f3f9; +} .bordered { - border-left: 2px solid #E6E6E6; } + border-left: 2px solid #E6E6E6; +} .bg-purple { - background-color: #9e84c5; } + background-color: #9e84c5; +} .bg-light-purple { - background-color: #f7f3f9; } + background-color: #f7f3f9; +} .bg-orange { - background-color: #FFAC5E; } + background-color: #FFAC5E; +} .bg-green { - background-color: #BBF085; } + background-color: #BBF085; +} .bg-dark-green { - background-color: #86B457; } + background-color: #86B457; +} .bg-red { - background-color: #dd4e58; } + background-color: #dd4e58; +} .bg-gray { - background-color: #939393; } + background-color: #939393; +} .bg-light-gray { - background-color: #E6E6E6; } + background-color: #E6E6E6; +} .action-bar { - min-height: 50px; - padding-top: 10px; - padding-bottom: 10px; } + min-height: 50px; + padding-top: 10px; + padding-bottom: 10px; +} .ember-list-view { - overflow: auto; - position: relative; - margin-bottom: 30px; } + overflow: auto; + position: relative; + margin-bottom: 30px; +} .ember-list-item-view { - position: absolute; - width: 100%; } + position: absolute; + width: 100%; +} .scrollable { - overflow: auto; - height: 800px; - margin-bottom: 30px; } + overflow: auto; + height: 800px; + margin-bottom: 30px; +} .elip-overflow { - display: block; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; } + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} .do-logo { - opacity: 0.6; - margin-top: -3px; } + opacity: 0.6; + margin-top: -3px; +} /*# sourceMappingURL=base.css.map */ diff --git a/src/test/resources/consul_ui/static/base.css.map b/src/test/resources/consul_ui/static/base.css.map index 573c69f1..b6333075 100644 --- a/src/test/resources/consul_ui/static/base.css.map +++ b/src/test/resources/consul_ui/static/base.css.map @@ -1,7 +1,18 @@ { -"version": 3, -"mappings": "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", -"sources": ["../styles/_type.scss","../styles/_variables.scss","../styles/_mixins.scss","../styles/_panels.scss","../styles/_nav.scss","../styles/_buttons.scss","../styles/_lists.scss","../styles/_forms.scss","../styles/_notifications.scss","../styles/base.scss"], -"names": [], -"file": "base.css" + "version": 3, + "mappings": "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", + "sources": [ + "../styles/_type.scss", + "../styles/_variables.scss", + "../styles/_mixins.scss", + "../styles/_panels.scss", + "../styles/_nav.scss", + "../styles/_buttons.scss", + "../styles/_lists.scss", + "../styles/_forms.scss", + "../styles/_notifications.scss", + "../styles/base.scss" + ], + "names": [], + "file": "base.css" } diff --git a/src/test/resources/consul_ui/static/loading-cylon-purple.svg b/src/test/resources/consul_ui/static/loading-cylon-purple.svg index 7107d1e7..092b8289 100644 --- a/src/test/resources/consul_ui/static/loading-cylon-purple.svg +++ b/src/test/resources/consul_ui/static/loading-cylon-purple.svg @@ -1,11 +1,21 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/test/resources/etc/configserver.json b/src/test/resources/etc/configserver.json index a40a5044..82fb9b23 100644 --- a/src/test/resources/etc/configserver.json +++ b/src/test/resources/etc/configserver.json @@ -1,7 +1,7 @@ { - "service": { - "name": "configserver", - "address": "127.0.0.1", - "port": 8888 - } + "service": { + "name": "configserver", + "address": "127.0.0.1", + "port": 8888 + } }