Browse files

First commit of eureka.

  • Loading branch information...
1 parent 4dc1194 commit 53939453474e39a8a68236f940c72de043ea20bd Karthik Ranganathan committed Aug 24, 2012
Showing with 19,654 additions and 29 deletions.
  1. +0 −3 .gitconfig
  2. +0 −26 .gitignore
  3. +202 −0 LICENSE
  4. +131 −0 build.gradle
  5. +13 −0 codequality/HEADER
  6. +189 −0 codequality/checkstyle.xml
  7. +229 −0 eureka-client/src/main/java/com/netflix/appinfo/AbstractInstanceConfig.java
  8. +218 −0 eureka-client/src/main/java/com/netflix/appinfo/AmazonInfo.java
  9. +155 −0 eureka-client/src/main/java/com/netflix/appinfo/ApplicationInfoManager.java
  10. +148 −0 eureka-client/src/main/java/com/netflix/appinfo/CloudInstanceConfig.java
  11. +31 −0 eureka-client/src/main/java/com/netflix/appinfo/DataCenterInfo.java
  12. +195 −0 eureka-client/src/main/java/com/netflix/appinfo/EurekaInstanceConfig.java
  13. +52 −0 eureka-client/src/main/java/com/netflix/appinfo/HealthCheckCallback.java
  14. +65 −0 eureka-client/src/main/java/com/netflix/appinfo/HealthCheckResource.java
  15. +912 −0 eureka-client/src/main/java/com/netflix/appinfo/InstanceInfo.java
  16. +173 −0 eureka-client/src/main/java/com/netflix/appinfo/LeaseInfo.java
  17. +40 −0 eureka-client/src/main/java/com/netflix/appinfo/MyDataCenterInstanceConfig.java
  18. +290 −0 eureka-client/src/main/java/com/netflix/appinfo/PropertiesInstanceConfig.java
  19. +36 −0 eureka-client/src/main/java/com/netflix/discovery/BackupRegistry.java
  20. +384 −0 eureka-client/src/main/java/com/netflix/discovery/DefaultEurekaClientConfig.java
  21. +1,463 −0 eureka-client/src/main/java/com/netflix/discovery/DiscoveryClient.java
  22. +115 −0 eureka-client/src/main/java/com/netflix/discovery/DiscoveryManager.java
  23. +390 −0 eureka-client/src/main/java/com/netflix/discovery/EurekaClientConfig.java
  24. +40 −0 eureka-client/src/main/java/com/netflix/discovery/converters/Auto.java
  25. +784 −0 eureka-client/src/main/java/com/netflix/discovery/converters/Converters.java
  26. +90 −0 eureka-client/src/main/java/com/netflix/discovery/converters/EntityBodyConverter.java
  27. +64 −0 eureka-client/src/main/java/com/netflix/discovery/converters/JsonXStream.java
  28. +58 −0 eureka-client/src/main/java/com/netflix/discovery/converters/XmlXStream.java
  29. +205 −0 eureka-client/src/main/java/com/netflix/discovery/provider/DiscoveryJerseyProvider.java
  30. +36 −0 eureka-client/src/main/java/com/netflix/discovery/provider/ISerializer.java
  31. +44 −0 eureka-client/src/main/java/com/netflix/discovery/provider/Serializer.java
  32. +190 −0 eureka-client/src/main/java/com/netflix/discovery/shared/Application.java
  33. +445 −0 eureka-client/src/main/java/com/netflix/discovery/shared/Applications.java
  34. +125 −0 eureka-client/src/main/java/com/netflix/discovery/shared/EurekaJerseyClient.java
  35. +88 −0 eureka-client/src/main/java/com/netflix/discovery/shared/LookupService.java
  36. +51 −0 eureka-client/src/main/java/com/netflix/discovery/shared/Pair.java
  37. +53 −0 eureka-core/src/main/java/com/netflix/discovery/CurrentRequestVersion.java
  38. +329 −0 eureka-core/src/main/java/com/netflix/discovery/DefaultEurekaServerConfig.java
  39. +262 −0 eureka-core/src/main/java/com/netflix/discovery/EurekaBootStrap.java
  40. +357 −0 eureka-core/src/main/java/com/netflix/discovery/EurekaServerConfig.java
  41. +45 −0 eureka-core/src/main/java/com/netflix/discovery/EurekaServerConfigurationManager.java
  42. +780 −0 eureka-core/src/main/java/com/netflix/discovery/InstanceRegistry.java
  43. +912 −0 eureka-core/src/main/java/com/netflix/discovery/PeerAwareInstanceRegistry.java
  44. +79 −0 eureka-core/src/main/java/com/netflix/discovery/StatusFilter.java
  45. +53 −0 eureka-core/src/main/java/com/netflix/discovery/V1AwareInstanceInfoConverter.java
  46. +39 −0 eureka-core/src/main/java/com/netflix/discovery/Version.java
  47. +471 −0 eureka-core/src/main/java/com/netflix/discovery/cluster/PeerEurekaNode.java
  48. +116 −0 eureka-core/src/main/java/com/netflix/discovery/lease/Lease.java
  49. +79 −0 eureka-core/src/main/java/com/netflix/discovery/lease/LeaseManager.java
  50. +116 −0 eureka-core/src/main/java/com/netflix/discovery/resources/ASGResource.java
  51. +136 −0 eureka-core/src/main/java/com/netflix/discovery/resources/ApplicationResource.java
  52. +191 −0 eureka-core/src/main/java/com/netflix/discovery/resources/ApplicationsResource.java
  53. +256 −0 eureka-core/src/main/java/com/netflix/discovery/resources/InstanceResource.java
  54. +65 −0 eureka-core/src/main/java/com/netflix/discovery/resources/InstancesResource.java
  55. +424 −0 eureka-core/src/main/java/com/netflix/discovery/resources/ResponseCache.java
  56. +105 −0 eureka-core/src/main/java/com/netflix/discovery/resources/StatusResource.java
  57. +309 −0 eureka-core/src/main/java/com/netflix/discovery/util/AwsAsgUtil.java
  58. +316 −0 eureka-core/src/main/java/com/netflix/discovery/util/EIPManager.java
  59. +181 −0 eureka-core/src/main/java/com/netflix/discovery/util/EurekaMonitors.java
  60. +71 −0 eureka-core/src/main/java/com/netflix/discovery/util/MeasuredRate.java
  61. +139 −0 eureka-core/src/main/java/com/netflix/discovery/util/StatusInfo.java
  62. +406 −0 eureka-resources/src/main/resources/css/jquery-ui-1.7.2.custom.css
  63. +154 −0 eureka-resources/src/main/resources/css/main.css
  64. +4,376 −0 eureka-resources/src/main/resources/js/jquery-1.3.2.js
  65. +298 −0 eureka-resources/src/main/resources/js/jquery-ui-1.7.2.custom.min.js
  66. +38 −0 eureka-resources/src/main/resources/jsp/header.jsp
  67. +66 −0 eureka-resources/src/main/resources/jsp/lastN.jsp
  68. +24 −0 eureka-resources/src/main/resources/jsp/navbar.jsp
  69. +169 −0 eureka-resources/src/main/resources/jsp/status.jsp
  70. +44 −0 eureka-server/WEB-INF/web.xml
  71. +14 −0 eureka-server/conf/eureka-client-prod.properties
  72. +20 −0 eureka-server/conf/eureka-client-test.properties
  73. +26 −0 eureka-server/conf/eureka-client.properties
  74. +5 −0 eureka-server/conf/eureka-server-prod.properties
  75. +4 −0 eureka-server/conf/eureka-server-test.properties
  76. +4 −0 eureka-server/conf/eureka-server.properties
  77. +4 −0 eureka-server/conf/log4j.properties
  78. +74 −0 eureka-server/test/java/com/netflix/eureka/SampleEurekaClient.java
  79. +18 −0 gradle/check.gradle
  80. +43 −0 gradle/convention.gradle
  81. +5 −0 gradle/license.gradle
  82. +55 −0 gradle/maven.gradle
  83. +1 −0 gradle/netflix-oss.gradle
  84. +6 −0 gradle/release.gradle
  85. BIN gradle/wrapper/gradle-wrapper.jar
  86. +6 −0 gradle/wrapper/gradle-wrapper.properties
  87. +164 −0 gradlew
  88. +90 −0 gradlew.bat
  89. +1 −0 netflix-oss.gradle
  90. +4 −0 settings.gradle
View
3 .gitconfig
@@ -1,3 +0,0 @@
-[core]
-excludesfile = /root/.gitignore
-
View
26 .gitignore
@@ -1,26 +0,0 @@
-*.iml
-*.ipr
-*.iws
-*.class
-target/
-.svn/
-.DS_Store
-.classpath
-.idea
-.ivy2.cache
-.project
-.gradle/
-build/
-out/
-doc/
-dist/
-coverage/
-derby.log
-exhibitor.properties
-classes/
-.settings
-prod
-rpm
-.mymetadata
-
-
View
202 LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2012 Netflix, Inc.
+
+ 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.
View
131 build.gradle
@@ -0,0 +1,131 @@
+ext.releaseVersion = '1.0'
+ext.githubProjectName = 'eureka'
+group = 'com.netflix.eureka'
+
+buildscript {
+ repositories { mavenCentral() }
+}
+
+allprojects {
+ repositories { mavenCentral() }
+}
+
+//apply from: file('gradle/release.gradle') // Not fully tested
+apply from: file('gradle/convention.gradle')
+apply from: file('gradle/maven.gradle')
+apply from: file('gradle/check.gradle')
+//apply from: file('gradle/license.gradle') // Waiting for re-release
+
+subprojects {
+ // Closure to configure all the POM with extra info, common to all projects
+ pom {
+ project {
+ url "https://github.com/Netflix/${githubProjectName}"
+ scm {
+ connection "scm:git:git@github.com:Netflix/${githubProjectName}.git"
+ url "scm:git:git@github.com:Netflix/${githubProjectName}.git"
+ developerConnection "scm:git:git@github.com:Netflix/${githubProjectName}.git"
+ }
+ issueManagement {
+ system 'github'
+ url "https://github.com/Netflix/${githubProjectName}/issues"
+ }
+ }
+ }
+ group = "com.netflix.${githubProjectName}" // TEMPLATE: Set to organization of project
+}
+
+
+project(':eureka-client') {
+jar {
+ manifest {
+ attributes("Implementation-Title": "eureka-client", "Implementation-Version": version,'Build-Time-ISO-8601': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"))
+ }
+}
+
+
+ dependencies {
+ compile 'com.thoughtworks.xstream:xstream:1.4.2'
+ compile 'com.netflix.archaius:archaius-core:0.2.2'
+ compile 'javax.ws.rs:jsr311-api:1.1.1'
+ compile 'com.netflix.servo:servo-core:0.4.13'
+ compile 'com.sun.jersey:jersey-bundle:1.9.1'
+ compile 'com.sun.jersey.contribs:jersey-apache-client4:1.8'
+ compile 'org.apache.httpcomponents:httpclient:4.1.2'
+
+ }
+}
+
+project(':eureka-core') {
+
+jar {
+ manifest {
+ attributes("Implementation-Title": "eureka-core", "Implementation-Version": version,'Build-Time-ISO-8601': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"))
+ }
+ }
+
+
+ dependencies {
+ compile project(':eureka-client')
+ compile 'amazon:aws-java-sdk:1.3.4.1'
+ compile 'javax.servlet:servlet-api:2.4'
+ compile 'com.thoughtworks.xstream:xstream:1.4.2'
+ compile 'com.netflix.archaius:archaius-core:0.2.2'
+ compile 'javax.ws.rs:jsr311-api:1.1.1'
+ compile 'com.netflix.servo:servo-core:0.4.13'
+ compile 'com.sun.jersey:jersey-bundle:1.9.1'
+ compile 'com.sun.jersey.contribs:jersey-apache-client4:1.8'
+ compile 'org.apache.httpcomponents:httpclient:4.1.2'
+
+ }
+}
+
+project(':eureka-resources') {
+
+
+task copy(type: Copy) {
+ from '*'
+}
+
+
+jar {
+ manifest {
+ attributes("Implementation-Title": "eureka-resources", "Implementation-Version": version,'Build-Time-ISO-8601': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"))
+ }
+ }
+}
+
+
+project(':eureka-server') {
+ apply plugin: 'war'
+
+sourceSets {
+ main {
+ java {
+ srcDir 'test/java'
+ }
+ }
+
+task taskX(dependsOn: ':eureka-resources:copy') << {
+ println 'Copying resources from eureka-resources'
+ }
+
+
+war {
+ from '*' // adds a file-set to the root of the archive
+ webXml = file('WEB-INF/web.xml') // copies a file to WEB-INF/web.xml
+}
+ dependencies {
+ compile project(':eureka-client')
+ compile project(':eureka-core')
+ compile project(':eureka-resources')
+ providedCompile 'javax.servlet:servlet-api:2.4'
+
+ }
+
+}
+
+
+
+
+
View
13 codequality/HEADER
@@ -0,0 +1,13 @@
+Copyright 2012 Netflix, Inc.
+
+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.
View
189 codequality/checkstyle.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+ "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
+ "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
+
+<module name="Checker">
+
+ <!-- Checks that a package-info.java file exists for each package. -->
+ <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage -->
+ <!--
+ <module name="JavadocPackage">
+ <property name="allowLegacy" value="true"/>
+ </module>
+ -->
+
+ <!-- Checks whether files end with a new line. -->
+ <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
+ <module name="NewlineAtEndOfFile"/>
+
+ <!-- Checks that property files contain the same keys. -->
+ <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
+ <module name="Translation"/>
+
+ <!-- Checks for Size Violations. -->
+ <!-- See http://checkstyle.sf.net/config_sizes.html -->
+ <module name="FileLength"/>
+
+ <!-- Checks for whitespace -->
+ <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+ <module name="FileTabCharacter"/>
+
+ <!-- Miscellaneous other checks. -->
+ <!-- See http://checkstyle.sf.net/config_misc.html -->
+ <module name="RegexpSingleline">
+ <property name="format" value="\s+$"/>
+ <property name="minimum" value="0"/>
+ <property name="maximum" value="0"/>
+ <property name="message" value="Line has trailing spaces."/>
+ <property name="severity" value="info"/>
+ </module>
+
+ <module name="TreeWalker">
+
+ <!-- Checks for Javadoc comments. -->
+ <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+ <module name="JavadocMethod">
+ <property name="scope" value="package"/>
+ <property name="allowMissingParamTags" value="true"/>
+ <property name="allowMissingThrowsTags" value="true"/>
+ <property name="allowMissingReturnTag" value="true"/>
+ <property name="allowThrowsTagsForSubclasses" value="true"/>
+ <property name="allowUndeclaredRTE" value="true"/>
+ <property name="allowMissingPropertyJavadoc" value="true"/>
+ </module>
+ <module name="JavadocType">
+ <property name="scope" value="package"/>
+ </module>
+ <module name="JavadocVariable">
+ <property name="scope" value="package"/>
+ </module>
+ <module name="JavadocStyle">
+ <property name="checkEmptyJavadoc" value="true"/>
+ </module>
+
+ <!-- Checks for Naming Conventions. -->
+ <!-- See http://checkstyle.sf.net/config_naming.html -->
+ <module name="ConstantName"/>
+ <module name="LocalFinalVariableName"/>
+ <module name="LocalVariableName"/>
+ <module name="MemberName"/>
+ <module name="MethodName"/>
+ <module name="PackageName"/>
+ <module name="ParameterName"/>
+ <module name="StaticVariableName"/>
+ <module name="TypeName"/>
+
+ <!-- Checks for imports -->
+ <!-- See http://checkstyle.sf.net/config_import.html -->
+ <module name="AvoidStarImport"/>
+ <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+ <module name="RedundantImport"/>
+ <module name="UnusedImports"/>
+
+
+ <!-- Checks for Size Violations. -->
+ <!-- See http://checkstyle.sf.net/config_sizes.html -->
+ <module name="LineLength">
+ <!-- what is a good max value? -->
+ <property name="max" value="120"/>
+ <!-- ignore lines like "$File: //depot/... $" -->
+ <property name="ignorePattern" value="\$File.*\$"/>
+ <property name="severity" value="info"/>
+ </module>
+ <module name="MethodLength"/>
+ <module name="ParameterNumber"/>
+
+
+ <!-- Checks for whitespace -->
+ <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+ <module name="EmptyForIteratorPad"/>
+ <module name="GenericWhitespace"/>
+ <module name="MethodParamPad"/>
+ <module name="NoWhitespaceAfter"/>
+ <module name="NoWhitespaceBefore"/>
+ <module name="OperatorWrap"/>
+ <module name="ParenPad"/>
+ <module name="TypecastParenPad"/>
+ <module name="WhitespaceAfter"/>
+ <module name="WhitespaceAround"/>
+
+ <!-- Modifier Checks -->
+ <!-- See http://checkstyle.sf.net/config_modifiers.html -->
+ <module name="ModifierOrder"/>
+ <module name="RedundantModifier"/>
+
+
+ <!-- Checks for blocks. You know, those {}'s -->
+ <!-- See http://checkstyle.sf.net/config_blocks.html -->
+ <module name="AvoidNestedBlocks"/>
+ <module name="EmptyBlock">
+ <property name="option" value="text"/>
+ </module>
+ <module name="LeftCurly"/>
+ <module name="NeedBraces"/>
+ <module name="RightCurly"/>
+
+
+ <!-- Checks for common coding problems -->
+ <!-- See http://checkstyle.sf.net/config_coding.html -->
+ <!-- <module name="AvoidInlineConditionals"/> -->
+ <module name="DoubleCheckedLocking"/> <!-- MY FAVOURITE -->
+ <module name="EmptyStatement"/>
+ <module name="EqualsHashCode"/>
+ <module name="HiddenField">
+ <property name="ignoreConstructorParameter" value="true"/>
+ <property name="ignoreSetter" value="true"/>
+ <property name="severity" value="warning"/>
+ </module>
+ <module name="IllegalInstantiation"/>
+ <module name="InnerAssignment"/>
+ <module name="MagicNumber">
+ <property name="severity" value="warning"/>
+ </module>
+ <module name="MissingSwitchDefault"/>
+ <!-- Problem with finding exception types... -->
+ <module name="RedundantThrows">
+ <property name="allowUnchecked" value="true"/>
+ <property name="suppressLoadErrors" value="true"/>
+ <property name="severity" value="info"/>
+ </module>
+ <module name="SimplifyBooleanExpression"/>
+ <module name="SimplifyBooleanReturn"/>
+
+ <!-- Checks for class design -->
+ <!-- See http://checkstyle.sf.net/config_design.html -->
+ <!-- <module name="DesignForExtension"/> -->
+ <module name="FinalClass"/>
+ <module name="HideUtilityClassConstructor"/>
+ <module name="InterfaceIsType"/>
+ <module name="VisibilityModifier"/>
+
+
+ <!-- Miscellaneous other checks. -->
+ <!-- See http://checkstyle.sf.net/config_misc.html -->
+ <module name="ArrayTypeStyle"/>
+ <!-- <module name="FinalParameters"/> -->
+ <module name="TodoComment">
+ <property name="format" value="TODO"/>
+ <property name="severity" value="info"/>
+ </module>
+ <module name="UpperEll"/>
+
+ <module name="FileContentsHolder"/> <!-- Required by comment suppression filters -->
+
+ </module>
+
+ <!-- Enable suppression comments -->
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="CHECKSTYLE IGNORE\s+(\S+)"/>
+ <property name="onCommentFormat" value="CHECKSTYLE END IGNORE\s+(\S+)"/>
+ <property name="checkFormat" value="$1"/>
+ </module>
+ <module name="SuppressWithNearbyCommentFilter">
+ <!-- Syntax is "SUPPRESS CHECKSTYLE name" -->
+ <property name="commentFormat" value="SUPPRESS CHECKSTYLE (\w+)"/>
+ <property name="checkFormat" value="$1"/>
+ <property name="influenceFormat" value="1"/>
+ </module>
+</module>
View
229 eureka-client/src/main/java/com/netflix/appinfo/AbstractInstanceConfig.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *
+ * 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 com.netflix.appinfo;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.discovery.shared.Pair;
+
+/**
+ * An abstract instance info configuration with some defaults to get the users
+ * started quickly.The users have to override only a few methods to register
+ * their instance with eureka server.
+ *
+ * @author Karthik Ranganathan
+ *
+ */
+public abstract class AbstractInstanceConfig implements EurekaInstanceConfig {
+ private static final Logger logger = LoggerFactory
+ .getLogger(AbstractInstanceConfig.class);
+
+ private static final int LEASE_EXPIRATION_DURATION_SECONDS = 90;
+ private static final int LEASE_RENEWAL_INTERVAL_SECONDS = 30;
+ private static final boolean SECURE_PORT_ENABLED = false;
+ private static final boolean NON_SECURE_PORT_ENABLED = true;
+ private static final int NON_SECURE_PORT = 80;
+ private static final int SECURE_PORT = 443;
+ private static final boolean INSTANCE_ENABLED_ON_INIT = false;
+ private static final String UNKNOWN_APPLICATION = "unknown";
+ private static final Pair<String, String> hostInfo = getHostInfo();
+ private DataCenterInfo info = new DataCenterInfo() {
+ @Override
+ public Name getName() {
+ return Name.MyOwn;
+ }
+ };
+
+ protected AbstractInstanceConfig() {
+
+ }
+
+ protected AbstractInstanceConfig(DataCenterInfo info) {
+ this.info = info;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getAppname()
+ */
+ @Override
+ public abstract String getAppname();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#isInstanceEnabledOnit()
+ */
+ @Override
+ public boolean isInstanceEnabledOnit() {
+ return INSTANCE_ENABLED_ON_INIT;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getNonSecurePort()
+ */
+ @Override
+ public int getNonSecurePort() {
+ return NON_SECURE_PORT;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getSecurePort()
+ */
+ @Override
+ public int getSecurePort() {
+ return SECURE_PORT;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#isNonSecurePortEnabled()
+ */
+ @Override
+ public boolean isNonSecurePortEnabled() {
+ return NON_SECURE_PORT_ENABLED;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getSecurePortEnabled()
+ */
+ @Override
+ public boolean getSecurePortEnabled() {
+ // TODO Auto-generated method stub
+ return SECURE_PORT_ENABLED;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.netflix.appinfo.InstanceConfig#getLeaseRenewalIntervalInSeconds()
+ */
+ @Override
+ public int getLeaseRenewalIntervalInSeconds() {
+ return LEASE_RENEWAL_INTERVAL_SECONDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.netflix.appinfo.InstanceConfig#getLeaseExpirationDurationInSeconds()
+ */
+ @Override
+ public int getLeaseExpirationDurationInSeconds() {
+ return LEASE_EXPIRATION_DURATION_SECONDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getVirtualHostName()
+ */
+ @Override
+ public String getVirtualHostName() {
+ return (getHostName(false) + ":" + getNonSecurePort());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getSecureVirtualHostName()
+ */
+ @Override
+ public String getSecureVirtualHostName() {
+ return (getHostName(false) + ":" + getSecurePort());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getASGName()
+ */
+ @Override
+ public String getASGName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getHostName()
+ */
+ @Override
+ public String getHostName(boolean refresh) {
+ return hostInfo.second();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getMetadataMap()
+ */
+ @Override
+ public Map<String, String> getMetadataMap() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getDataCenterInfo()
+ */
+ @Override
+ public DataCenterInfo getDataCenterInfo() {
+ // TODO Auto-generated method stub
+ return info;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.InstanceConfig#getIpAddress()
+ */
+ @Override
+ public String getIpAddress() {
+ return hostInfo.first();
+ }
+
+ private static Pair<String, String> getHostInfo() {
+ Pair<String, String> pair = new Pair<String, String>("", "");
+ try {
+ pair.setFirst(InetAddress.getLocalHost().getHostAddress());
+ pair.setSecond(InetAddress.getLocalHost().getHostName());
+
+ } catch (UnknownHostException e) {
+ logger.error("Cannot get host info", e);
+ }
+ return pair;
+ }
+
+}
View
218 eureka-client/src/main/java/com/netflix/appinfo/AmazonInfo.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *
+ * 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 com.netflix.appinfo;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.config.DynamicBooleanProperty;
+import com.netflix.config.DynamicIntProperty;
+import com.thoughtworks.xstream.annotations.XStreamOmitField;
+
+/**
+ * An AWS specific {@link DataCenterInfo} implementation.
+ *
+ * <p>
+ * Gets AWS specific information for registration with eureka by making a HTTP
+ * call to an AWS service as recommended by AWS.
+ * </p>
+ *
+ * @author Karthik Ranganathan, Greg Kim
+ *
+ */
+public class AmazonInfo implements DataCenterInfo {
+
+ private Map<String, String> metadata = new HashMap<String, String>();
+ private static DynamicBooleanProperty shouldLogAWSMetadataError;
+ private static DynamicIntProperty awsMetaDataReadTimeout;
+ private static DynamicIntProperty awsMetaDataConnectTimeout;
+ private static DynamicIntProperty awsMetaDataRetries;
+
+ public enum MetaDataKey {
+ amiId("ami-id"), instanceId("instance-id"), instanceType(
+ "instance-type"), localIpv4("local-ipv4"), availabilityZone(
+ "availability-zone", "placement/"), publicHostname(
+ "public-hostname"), publicIpv4("public-ipv4");
+
+ private String name;
+ private String path;
+
+ MetaDataKey(String name) {
+ this(name, "");
+ }
+
+ MetaDataKey(String name, String path) {
+ this.name = name;
+ this.path = path;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPath() {
+ return path;
+ }
+ }
+
+ public static final class Builder {
+ private static final Logger logger = LoggerFactory
+ .getLogger(Builder.class);
+ private static final int SLEEP_TIME_MS = 100;
+ private final static String AWS_API_VERSION = "latest";
+ private final static String AWS_METADATA_URL = "http://169.254.169.254/"
+ + AWS_API_VERSION + "/meta-data/";
+
+ @XStreamOmitField
+ private AmazonInfo result;
+
+ private Builder() {
+ result = new AmazonInfo();
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ public Builder addMetadata(MetaDataKey key, String value) {
+ result.metadata.put(key.getName(), value);
+ return this;
+ }
+
+ /**
+ * Build the {@link InstanceInfo}
+ */
+ public AmazonInfo build() {
+ return result;
+ }
+
+ /**
+ * Build the {@link AmazonInfo} automatically via HTTP calls to instance
+ * metadata API.
+ * @param namespace the namespace to look for configuration properties.
+ * @return the instance information specific to AWS.
+ */
+ public AmazonInfo autoBuild(String namespace) {
+ initProperties(namespace);
+ for (MetaDataKey key : MetaDataKey.values()) {
+ int numOfRetries = awsMetaDataRetries.get();
+ while (numOfRetries-- > 0) {
+ try {
+ URL url = new URL(AWS_METADATA_URL + key.getPath()
+ + key.getName());
+ HttpURLConnection uc = (HttpURLConnection) url
+ .openConnection();
+ uc.setConnectTimeout(awsMetaDataConnectTimeout.get());
+ uc.setReadTimeout(awsMetaDataReadTimeout.get());
+
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(uc.getInputStream()));
+ String value = br.readLine();
+ if (value != null) {
+ result.metadata.put(key.getName(), value);
+ }
+ } catch (Throwable e) {
+ if (shouldLogAWSMetadataError.get()) {
+ logger.warn(
+ "Cannot get the value for the metadata key :"
+ + key + " Reason :", e);
+ }
+ if (numOfRetries >= 0) {
+ try {
+ Thread.sleep(SLEEP_TIME_MS);
+ } catch (InterruptedException e1) {
+
+ }
+ continue;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private void initProperties(String namespace) {
+ if (shouldLogAWSMetadataError == null) {
+ shouldLogAWSMetadataError = com.netflix.config.DynamicPropertyFactory
+ .getInstance().getBooleanProperty(
+ namespace + "logAmazonMetadataErrors", false);
+ }
+ if (awsMetaDataReadTimeout == null) {
+ awsMetaDataReadTimeout = com.netflix.config.DynamicPropertyFactory
+ .getInstance().getIntProperty(
+ namespace + "mt.read_timeout", 8000);
+ }
+ if (awsMetaDataConnectTimeout == null) {
+ awsMetaDataConnectTimeout = com.netflix.config.DynamicPropertyFactory
+ .getInstance().getIntProperty(
+ namespace + "mt.connect_timeout", 3000);
+ }
+ if (awsMetaDataRetries == null) {
+ awsMetaDataRetries = com.netflix.config.DynamicPropertyFactory
+ .getInstance().getIntProperty(namespace + "mt.num_retries",
+ 3);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.netflix.appinfo.DataCenterInfo#getName()
+ */
+ @Override
+ public Name getName() {
+ return Name.Amazon;
+ }
+
+ /**
+ * Get the metadata information specific to AWS.
+ *
+ * @return the map of AWS metadata as specified by {@link MetaDataKey}.
+ */
+ public Map<String, String> getMetadata() {
+ return metadata;
+ }
+
+ /**
+ * Set AWS metadata.
+ *
+ * @param metadataMap
+ * the map containing AWS metadata.
+ */
+ public void setMetadata(Map<String, String> metadataMap) {
+ this.metadata = metadataMap;
+ }
+
+ /**
+ * Gets the AWS metadata specified in {@link MetaDataKey}.
+ *
+ * @param key
+ * the metadata key.
+ * @return String returning the value.
+ */
+ public String get(MetaDataKey key) {
+ return metadata.get(key.getName());
+ }
+}
View
155 eureka-client/src/main/java/com/netflix/appinfo/ApplicationInfoManager.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *f
+ * 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 com.netflix.appinfo;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.appinfo.InstanceInfo.InstanceStatus;
+import com.netflix.appinfo.InstanceInfo.PortType;
+
+/**
+ * The class that initializes information required for registration with
+ * <tt>Eureka Server</tt> and to be discovered by other components.
+ *
+ * <p>
+ * The information required for registration is provided by the user by passing
+ * the configuration defined by the contract in {@InstanceConfig}.AWS clients can
+ * either use or extend {@CloudInstanceConfig}.Other non-AWS clients can use or
+ * extend either {@MyDataCenterInstanceConfig} or very basic {@AbstractInstanceConfig}.
+ * </p>
+ *
+ *
+ * @author Karthik Ranganathan, Greg Kim
+ *
+ */
+public class ApplicationInfoManager {
+ private static final Logger logger = LoggerFactory
+ .getLogger(ApplicationInfoManager.class);
+ private static final ApplicationInfoManager instance = new ApplicationInfoManager();
+ private InstanceInfo instanceInfo;
+ private EurekaInstanceConfig config;
+
+ private ApplicationInfoManager() {
+ }
+
+ public static ApplicationInfoManager getInstance() {
+ return instance;
+ }
+
+ public void initComponent(EurekaInstanceConfig config) {
+ try {
+ this.config = config;
+ // Build the lease information to be passed to the server based
+ // on config
+ LeaseInfo.Builder leaseInfoBuilder = LeaseInfo.Builder
+ .newBuilder()
+ .setRenewalIntervalInSecs(
+ config.getLeaseRenewalIntervalInSeconds())
+ .setDurationInSecs(
+ config.getLeaseExpirationDurationInSeconds());
+
+ // Builder the instance information to be registered with eureka
+ // server
+ InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder();
+
+ builder.setAppName(config.getAppname())
+ .setDataCenterInfo(config.getDataCenterInfo())
+ .setIPAddr(config.getIpAddress())
+ .setHostName(config.getHostName(false))
+ .setPort(config.getNonSecurePort())
+ .enablePort(PortType.UNSECURE,
+ config.isNonSecurePortEnabled())
+ .setSecurePort(config.getSecurePort())
+ .enablePort(PortType.SECURE, config.getSecurePortEnabled())
+ .setVIPAddress(config.getVirtualHostName())
+ .setSecureVIPAddress(config.getSecureVirtualHostName())
+ .setASGName(config.getASGName());
+
+ // Start off with the STARTING state to avoid traffic
+ if (!config.isInstanceEnabledOnit()) {
+ builder.setStatus(InstanceStatus.STARTING);
+ }
+
+ // Add any user-specific metadata information
+ for (Map.Entry<String, String> mapEntry : config.getMetadataMap()
+ .entrySet()) {
+ String key = mapEntry.getKey();
+ String value = mapEntry.getValue();
+ builder.add(key, value);
+ }
+ instanceInfo = builder.build();
+ instanceInfo.setLeaseInfo(leaseInfoBuilder.build());
+
+ } catch (Throwable e) {
+ throw new RuntimeException(
+ "Failed to initialize ApplicationInfoManager", e);
+ }
+ }
+
+ /**
+ * Gets the information about this instance that is registered with
+ * eureka.
+ *
+ * @return information about this instance that is registered with
+ * eureka.
+ */
+ public InstanceInfo getInfo() {
+ return instanceInfo;
+ }
+
+ /**
+ * Register user-specific instance metadata. Application can send any other
+ * additional metadata that need to be accessed for other reasons.The data
+ * will be periodically sent to the eureka server.
+ */
+ public void registerAppMetadata(Map<String, String> appMetadata) {
+ instanceInfo.registerRuntimeMetadata(appMetadata);
+ }
+
+ /**
+ * Set the status of this instance. Application can use this to indicate
+ * whether it is ready to receive traffic.
+ *
+ * @param status
+ * Status of the instance
+ */
+ public void setInstanceStatus(InstanceStatus status) {
+ instanceInfo.setStatus(status);
+ }
+
+ /**
+ * Refetches the hostname to check if it has changed. If it has, the entire
+ * <code>DataCenterInfo</code> is refetched and passed on to the eureka
+ * server on next heartbeat.
+ */
+ public void refreshDataCenterInfoIfRequired() {
+ String existingHostname = instanceInfo.getHostName();
+ String newHostname = config.getHostName(true);
+ if (newHostname != null && !newHostname.equals(existingHostname)) {
+ logger.warn("The public hostname changed from : "
+ + existingHostname + " => " + newHostname);
+ InstanceInfo.Builder builder = new InstanceInfo.Builder(
+ instanceInfo);
+ builder.setHostName(newHostname).setDataCenterInfo(
+ config.getDataCenterInfo());
+ instanceInfo.setIsDirty(true);
+ }
+ }
+}
View
148 eureka-client/src/main/java/com/netflix/appinfo/CloudInstanceConfig.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *
+ * 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 com.netflix.appinfo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.appinfo.AmazonInfo.MetaDataKey;
+import com.netflix.appinfo.DataCenterInfo.Name;
+import com.netflix.config.DynamicBooleanProperty;
+import com.netflix.config.DynamicPropertyFactory;
+
+/**
+ * An {@link InstanceInfo} configuration for AWS cloud deployments.
+ *
+ * <p>
+ * The information required for registration with eureka by a combination of
+ * user-supplied values as well as querying AWS instance metadata.An utility
+ * class {@link AmazonInfo} helps in retrieving AWS specific values. Some of
+ * that information including <em>availability zone</em> is used for determining
+ * which eureka server to communicate to.
+ * </p>
+ *
+ * @author Karthik Ranganathan
+ *
+ */
+public class CloudInstanceConfig extends PropertiesInstanceConfig {
+ private static final Logger logger = LoggerFactory
+ .getLogger(CloudInstanceConfig.class);
+ private static final DynamicPropertyFactory INSTANCE = com.netflix.config.DynamicPropertyFactory
+ .getInstance();
+ private DynamicBooleanProperty propValidateInstanceId;
+ private DataCenterInfo info;
+
+ public CloudInstanceConfig() {
+ initCloudInstanceConfig(namespace);
+ }
+ public CloudInstanceConfig(String namespace) {
+ super(namespace);
+ initCloudInstanceConfig(namespace);
+ }
+ private void initCloudInstanceConfig(String namespace) {
+ propValidateInstanceId = INSTANCE.getBooleanProperty(namespace
+ + "validateInstanceId", true);
+ info = initDataCenterInfo();
+ }
+
+ private DataCenterInfo initDataCenterInfo() {
+ DataCenterInfo info;
+ try {
+ info = AmazonInfo.Builder.newBuilder().autoBuild(namespace);
+ logger.info("Datacenter is: " + Name.Amazon);
+ } catch (Throwable e) {
+ logger.error("Cannot initialize amazon info :", e);
+ throw new RuntimeException(e);
+ }
+ // Instance id being null means we could not get the amazon metadata
+ AmazonInfo amazonInfo = (AmazonInfo) info;
+ if (amazonInfo.get(MetaDataKey.instanceId) == null) {
+ if (propValidateInstanceId.get()) {
+ throw new RuntimeException(
+ "Your datacenter is defined as cloud but we are not able to get the amazon metadata to register. \n"
+ + "Set the property " + namespace + "validateInstanceId to false to ignore the metadata call");
+ }
+ // The property to not validate instance ids may be set for
+ // development and in that scenario, populate instance id
+ // and public hostname with the hostname of the machine
+ else {
+ Map<String, String> metadataMap = new HashMap<String, String>();
+ metadataMap.put(MetaDataKey.instanceId.getName(),
+ super.getIpAddress());
+ metadataMap.put(MetaDataKey.publicHostname.getName(),
+ super.getHostName(false));
+ amazonInfo.setMetadata(metadataMap);
+ }
+ }
+ // This might be a case of VPC where the instance id is not null, but
+ // public hostname might be null
+ else if ((amazonInfo.get(MetaDataKey.publicHostname) == null)
+ && (amazonInfo.get(MetaDataKey.localIpv4) != null)) {
+ amazonInfo.getMetadata().put(MetaDataKey.publicHostname.getName(),
+ (amazonInfo.get(MetaDataKey.localIpv4)));
+ }
+ return info;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.netflix.appinfo.AbstractInstanceConfig#getHostName()
+ */
+ @Override
+ public String getHostName(boolean refresh) {
+ if (refresh) {
+ refreshAmazonInfo();
+ }
+ return ((AmazonInfo) info).get(MetaDataKey.publicHostname);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.netflix.appinfo.AbstractInstanceConfig#getDataCenterInfo()
+ */
+ @Override
+ public DataCenterInfo getDataCenterInfo() {
+ return info;
+ }
+
+ /**
+ * Refresh instance info - currently only used when in AWS cloud
+ * as a public ip can change whenever an EIP is associated or dissociated.
+ */
+ public synchronized void refreshAmazonInfo() {
+ try {
+ AmazonInfo newInfo = AmazonInfo.Builder.newBuilder()
+ .autoBuild(namespace);
+ String newHostname = newInfo.get(MetaDataKey.publicHostname);
+ String existingHostname = ((AmazonInfo) info)
+ .get(MetaDataKey.publicHostname);
+ if (newHostname != null
+ && !newHostname.equals(existingHostname)) {
+ // public dns has changed on us, re-sync it
+ logger.warn("The public hostname changed from : "
+ + existingHostname + " => " + newHostname);
+ this.info = newInfo;
+ }
+ } catch (Throwable t) {
+ logger.error("Cannot refresh the Amazon Info ", t);
+ }
+ }
+
+}
View
31 eureka-client/src/main/java/com/netflix/appinfo/DataCenterInfo.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *
+ * 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 com.netflix.appinfo;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ * A simple interface for indicating which <em>datacenter</em> a particular instance belongs.
+ *
+ * @author Karthik Ranganathan
+ *
+ */
+@XStreamAlias("datacenter")
+public interface DataCenterInfo {
+ enum Name {Netflix, Amazon, MyOwn};
+ Name getName();
+}
View
195 eureka-client/src/main/java/com/netflix/appinfo/EurekaInstanceConfig.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *
+ * 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 com.netflix.appinfo;
+
+import java.util.Map;
+
+/**
+ * Configuration information required by the instance to register with Eureka
+ * server. Once registered, users can look up information from
+ * {@link DiscoveryClient} based on virtual hostname (also called VIPAddress),
+ * the most common way of doing it or by other means to get the information
+ * necessary to talk to other instances registered with <em>Eureka</em>.
+ *
+ *
+ * <p>
+ * Note that all configurations are not effective at runtime unless
+ * and otherwise specified.
+ * </p>
+ *
+ * @author Karthik Ranganathan
+ *
+ */
+public interface EurekaInstanceConfig {
+ /**
+ * Get the name of the application to be registered with eureka.
+ *
+ * @return string denoting the name.
+ */
+ String getAppname();
+
+ /**
+ * Indicates whether the instance should be enabled for taking traffic as
+ * soon as it is registered with eureka. Sometimes the application might
+ * need to do some pre-processing before it is ready to take traffic.
+ *
+ * @return true to immediately start taking traffic, false otherwise.
+ */
+ boolean isInstanceEnabledOnit();
+
+ /**
+ * Get the <code>non-secure</code> port on which the instance should receive
+ * traffic.
+ *
+ * @return the non-secure port on which the instance should receive traffic.
+ */
+ int getNonSecurePort();
+
+ /**
+ * Get the <code>Secure port</code> on which the instance should receive
+ * traffic.
+ *
+ * @return the non-secure port on which the instance should receive traffic.
+ */
+ int getSecurePort();
+
+ /**
+ * Indicates whether the <code>non-secure</code> port should be enabled for
+ * traffic or not.
+ *
+ * @return true if the <code>non-secure</code> port is enabled, false
+ * otherwise.
+ */
+ boolean isNonSecurePortEnabled();
+
+ /**
+ * Indicates whether the <code>secure</code> port should be enabled for
+ * traffic or not.
+ *
+ * @return true if the <code>secure</code> port is enabled, false otherwise.
+ */
+ boolean getSecurePortEnabled();
+
+ /**
+ * Indicates how often (in seconds) the eureka client needs to send
+ * heartbeats to eureka server to indicate that it is still alive. If the
+ * heartbeats are not received for the period specified in
+ * {@link #getLeaseExpirationDurationInSeconds()}, eureka server will remove
+ * the instance from its view, there by disallowing traffic to this
+ * instance.
+ *
+ * <p>
+ * Note that the instance could still not take traffic if it implements
+ * {@link HealhCheckCallback} and then decides to make itself unavailable.
+ * </p>
+ *
+ * @return time in seconds
+ */
+ int getLeaseRenewalIntervalInSeconds();
+
+ /**
+ * Indicates the time in seconds that the eureka server waits since it
+ * received the last heartbeat before it can remove this instance from its
+ * view and there by disallowing traffic to this instance.
+ *
+ * <p>
+ * Setting this value too long could mean that the traffic could be routed
+ * to the instance even though the instance is not alive. Setting this value
+ * too small could mean, the instance may be taken out of traffic because of
+ * temporary network glitches.This value to be set to atleast higher than
+ * the value specified in {@Link #getLeaseRenewalIntervalInSeconds()}
+ * .
+ * </p>
+ *
+ * @return
+ */
+ int getLeaseExpirationDurationInSeconds();
+
+ /**
+ * Gets the virtual host name defined for this instance.
+ *
+ * <p>
+ * This is typically the way other instance would find this instance by
+ * using the virtual host name.Think of this as similar to the fully
+ * qualified domain name, that the users of your services will need to find
+ * this instance.
+ * </p>
+ *
+ * @return
+ */
+ String getVirtualHostName();
+
+ /**
+ * Gets the secure virtual host name defined for this instance.
+ *
+ * <p>
+ * This is typically the way other instance would find this instance by
+ * using the secure virtual host name.Think of this as similar to the fully
+ * qualified domain name, that the users of your services will need to find
+ * this instance.
+ * </p>
+ *
+ * @return
+ */
+ String getSecureVirtualHostName();
+
+ /**
+ * Gets the <code>AWS autoscaling group name</code> associated with this
+ * instance. This information is specifically used in an AWS environment to
+ * automatically put an instance out of service after the instance is
+ * launched and it has been disabled for traffic..
+ *
+ * @return the autoscaling group name associated with this instance.
+ */
+ String getASGName();
+
+ /**
+ * Gets the hostname associated with this instance. This is the exact name
+ * that would be used by other instances to make calls.
+ *
+ * @param refresh true if the information needs to be refetched, false otherwise.
+ * @return hostname of this instance which is identifiable by other
+ * instances for making remote calls.
+ */
+ String getHostName(boolean refresh);
+
+ /**
+ * Gets the metadata name/value pairs associated with this instance. This
+ * information is sent to eureka server and can be used by other instances.
+ *
+ * @return Map containing application-specific metadata.
+ */
+ Map<String, String> getMetadataMap();
+
+ /**
+ * Returns the data center this instance is deployed. This information is
+ * used to get some AWS specific instance information if the instance is
+ * deployed in AWS.
+ *
+ * @return information that indicates which data center this instance is
+ * deployed in.
+ */
+ DataCenterInfo getDataCenterInfo();
+
+ /**
+ * Get the IPAdress of the instance. This information is for academic
+ * purposes only as the communication from other instances primarily happen
+ * using the information supplied in {@link #getHostName()}.
+ *
+ * @return the ip address of this instance.
+ */
+ String getIpAddress();
+}
View
52 eureka-client/src/main/java/com/netflix/appinfo/HealthCheckCallback.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *
+ * 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 com.netflix.appinfo;
+
+import com.netflix.discovery.DiscoveryClient;
+
+/**
+ * Applications can implement this interface and register a callback with the
+ * {@link DiscoveryClient#registerHealthCheckCallback(HealthCheckCallback)}.
+ *
+ * <p>
+ * Your callback will be invoked every
+ * {@link EurekaInstanceConfig#getLeaseRenewalIntervalInSeconds()} if the
+ * instance is in {@link InstanceInfo.InstanceStatus#STARTING} status, we will
+ * delay the callback until the status changes.Returning a false to the
+ * checkHealth() method will mark the instance
+ * {@link InstanceInfo.InstanceStatus#DOWN} with eureka.
+ * </p>
+ *
+ * <p>
+ * Eureka server normally just relies on <em>heartbeats</em> to identify the
+ * <em>status</em> of an instance. Application could decide to implement their
+ * own <em>healthpage</em> check here or use the built-in jersey resource
+ * {@link HealthCheckResource}.
+ * </p>
+ *
+ * @author Karthik Ranganathan, Greg Kim
+ */
+public interface HealthCheckCallback {
+ /**
+ * If false, the instance will be marked
+ * {@link InstanceInfo.InstanceStatus#DOWN} with eureka. If the instance was
+ * already marked {@link InstanceInfo.InstanceStatus#DOWN} , returning true
+ * here will mark the instance back to
+ * {@link InstanceInfo.InstanceStatus#UP}
+ */
+ boolean isHealthy();
+}
View
65 eureka-client/src/main/java/com/netflix/appinfo/HealthCheckResource.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *
+ * 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 com.netflix.appinfo;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A basic <em>healthcheck</em> jersey resource.
+ *
+ * This can be used a {@link HealthCheckCallback} resource if required.
+ * @author Karthik Ranganathan, Greg Kim
+ *
+ */
+@Path("/healthcheck")
+public class HealthCheckResource {
+ private static final Logger s_logger = LoggerFactory
+ .getLogger(HealthCheckResource.class);
+
+ @GET
+ public Response doHealthCheck() {
+ try {
+ InstanceInfo myInfo = ApplicationInfoManager.getInstance()
+ .getInfo();
+
+ switch (myInfo.getStatus()) {
+ case UP:
+ // Return status 200
+ return Response.status(Status.OK).build();
+ case STARTING:
+ // Return status 204
+ return Response.status(Status.NO_CONTENT).build();
+ case OUT_OF_SERVICE:
+ // Return 503
+ return Response.status(Status.SERVICE_UNAVAILABLE).build();
+ default:
+ // Return status 500
+ return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ }
+ } catch (Throwable th) {
+ s_logger.error("Error doing healthceck", th);
+ // Return status 500
+ return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ }
+ }
+}
View
912 eureka-client/src/main/java/com/netflix/appinfo/InstanceInfo.java
@@ -0,0 +1,912 @@
+/*
+ * Copyright 2012 Netflix, Inc.
+ *
+ * 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 com.netflix.appinfo;
+
+import java.net.URL;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.appinfo.AmazonInfo.MetaDataKey;
+import com.netflix.appinfo.DataCenterInfo.Name;
+import com.netflix.config.DynamicPropertyFactory;
+import com.netflix.discovery.DiscoveryClient;
+import com.netflix.discovery.converters.Auto;
+import com.netflix.discovery.provider.Serializer;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamOmitField;
+
+/**
+ * The class that holds information required for registration with
+ * <tt>Eureka Server</tt> and to be discovered by other components.
+ * <p>
+ * <code>@Auto</code> annotated fields are serialized as is; Other fields are
+ * serialized as specified by the <code>@Serializer</code>.
+ * </p>
+ *
+ * @author Karthik Ranganathan, Greg Kim
+ *
+ */
+@Serializer("com.netflix.discovery.converters.EntityBodyConverter")
+@XStreamAlias("instance")
+public class InstanceInfo {
+ private static final Logger logger = LoggerFactory
+ .getLogger(InstanceInfo.class);
+ private static final Pattern VIP_ATTRIBUTES_PATTERN = Pattern
+ .compile("\\$\\{(.*?)\\}");
+
+ public final static int DEFAULT_PORT = 7001;
+ public final static int DEFAULT_SECURE_PORT = 7002;
+ public final static int DEFAULT_COUNTRY_ID = 1; // US
+ private volatile String appName;
+ private volatile String ipAddr;
+ private volatile String sid = "na";
+
+ private volatile int port = DEFAULT_PORT;
+ private volatile int securePort = DEFAULT_SECURE_PORT;
+
+ @Auto
+ private volatile String homePageUrl;
+ @Auto
+ private volatile String statusPageUrl;
+ @Auto
+ private volatile String healthCheckUrl;
+ @Auto
+ private volatile String secureHealthCheckUrl;
+ @Auto
+ private volatile String vipAddress;
+ @Auto
+ private volatile String secureVipAddress;
+ @XStreamOmitField
+ private String statusPageRelativeUrl;
+ @XStreamOmitField
+ private String statusPageExplicitUrl;
+ @XStreamOmitField
+ private String healthCheckRelativeUrl;
+ @XStreamOmitField
+ private String healthCheckSecureExplicitUrl;
+ @XStreamOmitField
+ private String vipAddressUnresolved;
+ @XStreamOmitField
+ private String secureVipAddressUnresolved;
+ @XStreamOmitField
+ private String healthCheckExplicitUrl;
+ @Deprecated
+ private volatile int countryId = DEFAULT_COUNTRY_ID; // Defaults to US
+ private volatile boolean isSecurePortEnabled = false;
+ private volatile boolean isUnsecurePortEnabled = true;
+ private volatile DataCenterInfo dataCenterInfo;
+ private volatile String hostName;
+ private volatile InstanceStatus status = InstanceStatus.UP;
+ private volatile InstanceStatus overriddenstatus = InstanceStatus.UNKNOWN;
+ @XStreamOmitField
+ private volatile boolean isInstanceInfoDirty = false;
+ private volatile LeaseInfo leaseInfo;
+ @Auto
+ private volatile Boolean isCoordinatingDiscoveryServer = Boolean.FALSE;
+ @XStreamAlias("metadata")
+ private volatile Map<String, String> metadata = new ConcurrentHashMap<String, String>();
+ @Auto
+ private volatile Long lastUpdatedTimestamp = System.currentTimeMillis();
+ @Auto
+ private volatile Long lastDirtyTimestamp = System.currentTimeMillis();
+ @Auto
+ private volatile ActionType actionType;
+ @Auto
+ private volatile String asgName;
+ private String version = "unknown";
+
+ private InstanceInfo() {
+ }
+
+ public enum InstanceStatus {
+ UP, // Ready to receive traffic
+ DOWN, // Do not send traffic- healthcheck callback failed
+ STARTING, // Just about starting- initializations to be done - do not
+ // send traffic
+ OUT_OF_SERVICE, // Intentionally shutdown for traffic
+ UNKNOWN;
+
+ public static InstanceStatus toEnum(String s) {
+ for (InstanceStatus e : InstanceStatus.values()) {
+ if (e.name().equalsIgnoreCase(s)) {
+ return e;
+ }
+ }
+ return UNKNOWN;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ InstanceInfo other = (InstanceInfo) obj;
+ if (getId() == null) {
+ if (other.getId() != null)
+ return false;
+ } else if (!getId().equals(other.getId()))
+ return false;
+ return true;
+ }
+
+ public enum PortType {
+ SECURE, UNSECURE
+ }
+
+ public static final class Builder {
+
+ private static final String HOSTNAME_INTERPOLATION_EXPRESSION = "${netflix.appinfo.hostname}";
+ private static final String COLON = ":";
+ private static final String HTTPS_PROTOCOL = "https://";
+ private static final String HTTP_PROTOCOL = "http://";
+
+ @XStreamOmitField
+ private InstanceInfo result;
+
+ private Builder() {
+ result = new InstanceInfo();
+ }
+
+ public Builder(InstanceInfo instanceInfo) {
+ result = instanceInfo;
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ /**
+ * Set the application name of the instance.This is mostly used in
+ * querying of instances.
+ *
+ * @param appName
+ * the application name.
+ * @return the instance info builder.
+ */
+ public Builder setAppName(String appName) {
+ result.appName = appName;
+ if (result.appName != null) {
+ result.appName = result.appName.toUpperCase();
+ }
+ return this;
+ }
+
+ /**
+ * Sets the fully qualified hostname of this running instance.This is
+ * mostly used in constructing the {@link URL} for communicating with
+ * the instance.
+ */
+ public Builder setHostName(String hostName) {
+ String existingHostName = result.hostName;
+ result.hostName = hostName;
+ if ((existingHostName != null) && !(hostName.equals(existingHostName))) {
+ refreshStatusPageUrl().refreshHealthCheckUrl()
+ .refreshVIPAddress().refreshSecureVIPAddress();
+ }
+ return this;
+ }
+
+ /**
+ * Sets the status of the instances.If the status is UP, that is when
+ * the instance is ready to service requests.
+ */
+ public Builder setStatus(InstanceStatus status) {
+ result.status = status;
+ return this;
+ }
+
+ /**
+ * Sets the status overridden by some other external process.This is
+ * mostly used in putting an instance out of service to block traffic to
+ * it.
+ */
+ public Builder setOverriddenStatus(InstanceStatus status) {
+ result.overriddenstatus = status;
+ return this;
+ }
+
+ /**
+ * Sets the ip address of this running instance.
+ */
+ public Builder setIPAddr(String ip) {
+ result.ipAddr = ip;
+ return this;
+ }
+
+
+ /**
+ * Sets the identity of this application instance.
+ */
+ @Deprecated
+ public Builder setSID(String sid) {
+ result.sid = sid;
+ return this;
+ }
+
+ /**
+ * Sets the port number that is used to service requests.
+ */
+ public Builder setPort(int port) {
+ result.port = port;
+ return this;
+ }
+
+ /**
+ * Sets the secured port that is used to service requests.
+ */
+ public Builder setSecurePort(int port) {
+ result.securePort = port;
+ return this;
+ }
+
+ /**
+ * Enabled or disable secure/non-secure ports .
+ *
+ * @param type
+ * Secure or Non-Secure.
+ * @param isEnabled
+ * true if enabled.
+ * @return the instance builder.
+ */
+ public Builder enablePort(PortType type, boolean isEnabled) {
+ if (type == PortType.SECURE) {
+ result.isSecurePortEnabled = isEnabled;
+ } else {
+ result.isUnsecurePortEnabled = isEnabled;
+ }
+ return this;
+ }
+
+ @Deprecated
+ public Builder setCountryId(int id) {
+ result.countryId = id;
+ return this;
+ }
+
+ /**
+ * Sets the absolute home page {@link URL} for this instance. The users
+ * can provide the <code>homePageUrlPath</code> if the home page resides
+ * in the same instance talking to discovery, else in the cases where
+ * the instance is a proxy for some other server, it can provide the
+ * full {@link URL}. If the full {@link URL} is provided it takes
+ * precedence.
+ *
+ * <p>
+ * The full {@link URL} should follow the format
+ * http://${netflix.appinfo.hostname}:7001/ where the value
+ * ${netflix.appinfo.hostname} is replaced at runtime.
+ * </p>
+ *
+ * @param homePageUrlPath
+ * - The {@link URL} path for home page for this instance
+ * @param explicitUrl
+ * - The full {@link URL} for the home page
+ * @return the instance builder.
+ */
+ public Builder setHomePageUrl(String relativeUrl, String explicitUrl) {
+ if (explicitUrl != null) {
+ result.homePageUrl = explicitUrl.replace(
+ HOSTNAME_INTERPOLATION_EXPRESSION, result.hostName);
+ } else if (relativeUrl != null) {
+ result.homePageUrl = HTTP_PROTOCOL + result.hostName + COLON
+ + result.port + relativeUrl;
+ }
+ return this;
+ }
+
+ /**
+ * Sets the absolute status page {@link URL} for this instance. The
+ * users can provide the <code>statusPageUrlPath</code> if the status
+ * page resides in the same instance talking to discovery, else in the
+ * cases where the instance is a proxy for some other server, it can
+ * provide the full {@link URL}. If the full {@link URL} is provided it
+ * takes precedence.
+ *
+ * <p>
+ * The full {@link URL} should follow the format
+ * http://${netflix.appinfo.hostname}:7001/Status where the value
+ * ${netflix.appinfo.hostname} is replaced at runtime.
+ * </p>
+ *
+ * @param relativeUrl
+ * - The {@link URL} path for status page for this instance
+ * @param explicitUrl
+ * - The full {@link URL} for the status page
+ * @return - Builder instance
+ */
+ public Builder setStatusPageUrl(String relativeUrl, String explicitUrl) {
+ result.statusPageRelativeUrl = relativeUrl;
+ result.statusPageExplicitUrl = explicitUrl;
+ if (explicitUrl != null) {
+ result.statusPageUrl = explicitUrl.replace(
+ HOSTNAME_INTERPOLATION_EXPRESSION, result.hostName);
+ } else if (relativeUrl != null) {
+ result.statusPageUrl = HTTP_PROTOCOL + result.hostName + COLON
+ + result.port + relativeUrl;
+ }
+ return this;
+ }
+
+ /**
+ * Sets the absolute health check {@link URL} for this instance for both
+ * secure and non-secure communication The users can provide the
+ * <code>healthCheckUrlPath</code> if the healthcheck page resides in
+ * the same instance talking to discovery, else in the cases where the
+ * instance is a proxy for some other server, it can provide the full
+ * {@link URL}. If the full {@link URL} is provided it takes precedence.
+ *
+ * <p>
+ * The full {@link URL} should follow the format
+ * http://${netflix.appinfo.hostname}:7001/healthcheck where the value
+ * ${netflix.appinfo.hostname} is replaced at runtime.
+ * </p>
+ *
+ * @param relativeUrl
+ * - The {@link URL} path for healthcheck page for this
+ * instance.
+ * @param explicitUrl
+ * - The full {@link URL} for the healthcheck page.
+ * @param securehealthCheckUrl
+ * - The full {@link URL} for the secure healthcheck page.
+ * @return the instance builder
+ */
+ public Builder setHealthCheckUrls(String relativeUrl,
+ String explicitUrl, String secureExplicitUrl) {
+ result.healthCheckRelativeUrl = relativeUrl;
+ result.healthCheckExplicitUrl = explicitUrl;
+ result.healthCheckSecureExplicitUrl = secureExplicitUrl;
+ if (explicitUrl != null) {
+ result.healthCheckUrl = explicitUrl.replace(
+ HOSTNAME_INTERPOLATION_EXPRESSION, result.hostName);
+ } else if (result.isUnsecurePortEnabled) {
+ result.healthCheckUrl = HTTP_PROTOCOL + result.hostName + COLON
+ + result.port + relativeUrl;
+ }
+
+ if (secureExplicitUrl != null) {
+ result.secureHealthCheckUrl = secureExplicitUrl.replace(
+ HOSTNAME_INTERPOLATION_EXPRESSION, result.hostName);
+ } else if (result.isSecurePortEnabled) {
+ result.secureHealthCheckUrl = HTTPS_PROTOCOL + result.hostName
+ + COLON + result.securePort + relativeUrl;
+ }
+ return this;
+ }
+
+ /**
+ * Sets the Virtual Internet Protocol address for this instance. The
+ * address should follow the format <code><hostname:port></code> This
+ * address needs to be resolved into a real address for communicating
+ * with this instance.
+ *
+ * @param vipAddress
+ * - The Virtual Internet Protocol address of this instance.
+ * @return the instance builder.
+ */
+ public Builder setVIPAddress(String vipAddress) {
+ result.vipAddressUnresolved = vipAddress;
+ result.vipAddress = resolveDeploymentContextBasedVipAddresses(vipAddress);
+ return this;
+ }
+
+ /**
+ * Sets the Secure Virtual Internet Protocol address for this instance.
+ * The address should follow the format <hostname:port> This address
+ * needs to be resolved into a real address for communicating with this
+ * instance.
+ *
+ * @param secureVipAddress
+ * - The Virtual Internet Protocol address of this instance
+ * @return - Builder instance
+ */
+ public Builder setSecureVIPAddress(String secureVIPAddress) {
+ result.secureVipAddressUnresolved = secureVIPAddress;
+ result.secureVipAddress = resolveDeploymentContextBasedVipAddresses(secureVIPAddress);
+ return this;
+ }
+
+ /**
+ * Sets the datacenter information.
+ */
+ public Builder setDataCenterInfo(DataCenterInfo datacenter) {
+ result.dataCenterInfo = datacenter;
+ return this;
+ }
+
+ /**
+ * Set the instance lease information.
+ *
+ * @param info
+ * the lease information for this instance.
+ */
+ public void setLeaseInfo(LeaseInfo info) {
+ result.leaseInfo = info;
+ }
+
+ /**
+ * Add arbitrary metadata to running instance
+ */
+ public Builder add(String key, String val) {
+ result.metadata.put(key, val);
+ return this;
+ }
+
+ /**
+ * Replace the existing metadata map with a new one.
+ *
+ * @param mt
+ * the new metadata name.
+ * @return instance info builder.
+ */
+ public Builder setMetadata(Map<String, String> mt) {
+ result.metadata = mt;
+ return this;
+ }
+
+ /**
+ * Returns the encapsulated instance info even it it is not built fully.
+ *
+ * @return the existing information about the instance.
+ */
+ public InstanceInfo getRawInstance() {
+ return result;
+ }
+
+ /**
+ * Build the {@link InstanceInfo} object.
+ */
+ public InstanceInfo build() {
+ if (!isInitialized()) {
+ throw new IllegalStateException("name is required!");
+ }
+ return result;
+ }
+
+ public boolean isInitialized() {
+ return (result.appName != null);
+ }
+
+ /**
+ * Sets the AWS ASG name for this instance.
+ *
+ * @param asgName
+ * the asg name for this instance.
+ * @return the instance info builder.
+ */
+ public Builder setASGName(String asgName) {
+ result.asgName = asgName;
+ return this;
+ }
+
+ private Builder refreshStatusPageUrl() {
+ setStatusPageUrl(result.statusPageRelativeUrl,
+ result.statusPageExplicitUrl);
+ return this;
+ }
+
+ private Builder refreshHealthCheckUrl() {
+ setHealthCheckUrls(result.healthCheckRelativeUrl,
+ result.healthCheckExplicitUrl,
+ result.healthCheckSecureExplicitUrl);
+ return this;
+ }
+
+ private Builder refreshSecureVIPAddress() {
+ setSecureVIPAddress(result.secureVipAddressUnresolved);
+ return this;
+ }
+
+ private Builder refreshVIPAddress() {
+ setVIPAddress(result.vipAddressUnresolved);
+ return this;
+ }
+
+ }
+
+ /**
+ * Return the name of the application registering with discovery.
+ */
+ public String getAppName() {
+ return appName;
+ }
+
+ /**
+ * Returns the fully qualified hostname of this running instance
+ * @return the hostname.
+ */
+ public String getHostName() {
+ return hostName;
+ }
+
+ @Deprecated
+ public void setSID(String sid) {
+ this.sid = sid;
+ setIsDirty(true);
+ }
+
+ @Deprecated
+ public String getSID() {
+ return sid;
+ }
+
+ /**
+ *
+ * Returns the unique id of the instance.
+ * @return the unique id.
+ */
+ public String getId() {
+ if (dataCenterInfo.getName() == Name.Amazon) {
+ return ((AmazonInfo) dataCenterInfo).get(MetaDataKey.instanceId);
+ } else {
+ return hostName;
+ }
+ }
+
+ /**
+ * Returns the ip address of the instance.